方法定义是ClojureScript中函数调用的结果

时间:2013-02-03 20:44:38

标签: clojure clojurescript

以下是Knockout的JS示例:

function AppViewModel() {
    this.firstName = ko.observable('Bob');
    this.lastName = ko.observable('Smith');
    this.fullName = ko.computed(function() {
        return this.firstName() + " " + this.lastName();
    }, this);
}

如果您不熟悉KO,AppViewModel上的每个字段都会成为一个函数(即ko.observableko.computed各自返回一个函数。另请注意fullName取决于关于这两个功能。

如何将其重写为ClojureScript?

要尝试的一件事是:

(deftype AppViewModel [firstName lastName]
  Object
  (fullName [this] (.computed js/ko (str (firstName) " " (lastName)))))

(defn my-model [first last]
  (AppViewModel. 
    (.observable js/ko "Bob") 
    (.observable js/ko "Smith")))

它不起作用,因为fullName成为调用ko.computed的函数。也就是说,它编译为:

my_namespace.AppViewModel.prototype.fullName = function() {
  return ko.computed([cljs.core.str(this.firstName.call(null)), cljs.core.str(" "), cljs.core.str(this.lastName.call(null))].join(""))
};

如何在ClojureScript中处理它?<​​/ p>

再次注意fullNamethisfirstName / lastName的依赖关系。

2 个答案:

答案 0 :(得分:3)

试试这个:

(defn my-model [first last]
  (let [fname (.observable js/ko first)
        lname (.observable js/ko last)
        full-name (.computed js/ko #(str (fname) " " (lname)))] 
        (js-obj "firstName" fname
                "lastName" lname
                "fullName" full-name)))

答案 1 :(得分:1)

对@ Ankur的回答嗤之以鼻,似乎你也可以做到以下几点:

  (deftype AppViewModel [firstName lastName fullName])

  (defn my-model [first last]
    (AppViewModel. 
      (.observable js/ko "Bob") 
      (.observable js/ko "Smith")
      (.computed js/ko (str (firstName) " " (lastName)))))