2

我想使用 Clojurescript 在 Javascript 框架中编写组件,但我不知道如何创建构造函数并在对象中调用全局变量。

该框架通过从保存的 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);
  }
})();

我已经看到了如何使用 deftype 宏和对象创建 Javascript 对象:

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

我是 javascript 和 clojurescript 的新手。我看到包装所有内容的匿名函数为视图提供了一个范围,但不确定如何(或如果我需要)因此在 clojurescript 中等效。

所以我的问题是:如何在这个模型中为 Title 创建构造函数?我应该如何处理对视图变量的调用,例如 view.inherit 等?

谢谢

4

1 回答 1

1

这是一个有点笼统的答案,但您似乎希望在 ClojureScript 和 JavaScript 之间共享代码,所以这里有一个入门和一些关于在 Clojure 中使用 JavaScript 库的精选花絮:


出口

保护您声明的符号免于重命名很容易;只需在任何 ClojureScript var 上定义:export元数据,ClojureScript 编译器就会确保它不会被修改。

例如,一个函数可以这样声明:

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

然后,它可以通过相同的名称在外部 JavaScript 上下文中使用:

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

外部人员

为了走另一条路,并从代码中引用外部声明的变量,您必须为 Google Closure 编译器提供一个“外部文件”,一个 .js 文件,用于定义不会被修改的 javascript 变量。该文件被传递给 Google Closure 编译器,并且在编译时,它不会修改其中定义的任何名称。

例如,我可以尝试在没有外部文件的情况下以高级模式编译以下 ClojureScript(利用 Raphael.js 库)。

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

当我调用该test函数时,它会抛出一个new Raphael(10, 50, 320, 200)).K is not a function. K是 Raphael 的 circle 函数的名称,显然找不到,因为它没有在任何地方定义。我们需要告诉编译器保留名称 circle,而不是 munge。

我可以通过创建以下 externs.js 文件来做到这一点:

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

并在编译我的 ClojureScript 时使用它:

(closure/build "src/cljs" {:optimizations :advanced
                           :externs ["externs.js"]
                           :output-to "helloworld.js"})
于 2015-11-18T01:54:16.777 回答