简体   繁体   English

将clojurescript集成到javascript框架中

[英]Integration clojurescript into a javascript framework

I would like to use Clojurescript to write a component within a Javascript framework but I can't work out how to create the constructor and call global variables within the object. 我想使用Clojurescript在Javascript框架内编写组件,但无法解决如何创建构造函数并在对象内调用全局变量的问题。

The framework creates views (within their own .js file) by reading their state from a saved jason file and reifying them in javascript (the views are code like so): 该框架通过从保存的jason文件中读取状态并在javascript中对其进行修改来创建视图(在其自己的.js文件中)(这些视图的代码如下):

(function() {

  var Title = function(json) {
    view.View.call(this, json);  // view is defined in another js file - global namespace
    this.title = json.title;
    this.el.addClass("title");

  }

  view.inherit(view.View, Title);
  view.Title = Title;
  view.types.Title = Title;

  Title.prototype.json = function() {
    return $.extend(view.View.prototype.json.call(this), {
      type: 'Title',
      title: this.title
    });
  }

  Title.prototype.reflow = function() {
    this.h2.quickfit(opts);
  }
})();

I have seen how you create a Javascript object using deftype macro and Object: 我已经看到了如何使用deftype宏和Object创建Javascript对象:

(deftype Foo [a b c]
   Object
   (bar x (+ a b c x)))

I'm new to both javascript and clojurescript. 我是javascript和clojurescript的新手。 I see that the anonymous function wrapping everything provides a scope for the view but not sure how to (or if I need to) so something equivalent in clojurescript. 我看到包装了所有内容的匿名函数为视图提供了作用域,但不确定如何(或是否需要),所以在clojurescript中也是如此。

So my questions are: how do I create the constructor function for Title in this model?? 所以我的问题是:如何在此模型中为Title创建构造函数? And do how should I handle the calls to the view variable, such as view.inherit etc? 我应该如何处理对view变量的调用,例如view.inherit等?

Thanks 谢谢

This is a bit general of an answer, but you seem to be wanting to share code between both ClojureScript and JavaScript, so here is a primer and a few select tidbits on Using JavaScript Libraries in Clojure : 这是一个一般的答案,但是您似乎想在ClojureScript和JavaScript之间共享代码,因此这是使用Clojure中使用JavaScript库的入门和一些选择:


Exporting 出口

Protecting symbols you declare from renaming is easy; 保护声明为重命名的符号很容易; just define :export metadata on any ClojureScript var, and the ClojureScript compiler will ensure that it is not munged. 只需在任何ClojureScript变量上定义:export元数据,ClojureScript编译器将确保它不会被删除。

For example, a function can be declared like this: 例如,可以这样声明一个函数:

(ns example)
(defn ^:export hello [name]
  (js/alert (str "Hello," name "!")))

It is then available, via the same name, in an external JavaScript context: 然后可以在外部JavaScript上下文中以相同的名称使用它:

<script>
    example.hello("Eustace")
</script>

Externs 外部

In order to go the other way, and reference a variable declared externally from within your code, you must provide the Google Closure compiler with an "extern file", a .js file defining javascript variables which will not be munged. 为了走另一条路,并从代码中引用在外部声明的变量,您必须为Google Closure编译器提供一个“外部文件”,这是一个.js文件,用于定义将不会被删除的javascript变量。 This file is passed to the Google Closure compiler, and when compiling, it will not munge any names defined in it. 该文件被传递到Google Closure编译器,并且在编译时不会删除其中定义的任何名称。

For example, I can try compiling the following ClojureScript (utilizing the Raphael.js library) in advanced mode without an extern file. 例如,我可以尝试在高级模式下编译以下ClojureScript(利用Raphael.js库)而无需extern文件。

(defn test []
  (let [raphael (js/Raphael. 10 50 320 200)]
    (. raphael (circle 50 50 50))))

When I call the test function, it will throw a javascript error that new Raphael(10, 50, 320, 200)).K is not a function . 当我调用test函数时,它将引发javascript错误,即new Raphael(10, 50, 320, 200)).K is not a function K is the munged name of the circle function from Raphael, and obviously can't be found, since it isn't defined anywhere. K是拉斐尔(Raphael)的圆函数的名字,由于没有在任何地方定义,因此显然找不到。 We need to tell the compiler to preserve the name circle, not munge it. 我们需要告诉编译器保留名称圈,而不是对其进行修改。

I can do this by creating the following externs.js file: 我可以通过创建以下externs.js文件来做到这一点:

var Raphael = {};
Raphael.circle = function() {};

And use it when compiling my ClojureScript: 并在编译ClojureScript时使用它:

(closure/build "src/cljs" {:optimizations :advanced
                           :externs ["externs.js"]
                           :output-to "helloworld.js"})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM