2012-06-04 3 views
5

knockout.js를 클로저로 감싸려고했지만 매우 어렵습니다. 문제는 'this'변수에 대한 참조입니다. 난 포기하고 그냥 자바 스크립트를 사용하여 생각하고 있어요.clojurescript를 사용하여 knockout.js 래핑

나는 몇 가지 매크로를 쉽게 기능을 래핑하는 관리했습니다 http://knockoutjs.com/examples/helloWorld.htmlhttp://knockoutjs.com/examples/contactsEditor.html

떨어져 예를 촬영했습니다. 예를 들어 :

var ViewModel = function() { 
    this.firstName = ko.observable("Bert"); 
    this.lastName = ko.observable("Bertington"); 

    this.fullName = ko.computed(function() { 
     // Knockout tracks dependencies automatically. It knows that fullName depends on firstName and lastName, because these get called when evaluating fullName. 
     return this.firstName() + " " + this.lastName(); 
    }, this); 
}; 

가된다 :

(defviewmodel data 
    (observing :first_name "Bert") 
    (observing :last_name "Bertington") 
    (computing :name [:first_name :last_name] 
    (str :first_name " " :last_name))) 

그러나, 열심히처럼 뭔가 :

var BetterListModel = function() { 
    this.itemToAdd = ko.observable(""); 
    this.allItems = ko.observableArray(["Fries", "Eggs Benedict", "Ham", "Cheese"]); // Initial items 
    this.selectedItems = ko.observableArray(["Ham"]);        // Initial selection 

    this.addItem = function() { 
     if ((this.itemToAdd() != "") && (this.allItems.indexOf(this.itemToAdd()) < 0)) // Prevent blanks and duplicates 
      this.allItems.push(this.itemToAdd()); 
     this.itemToAdd(""); // Clear the text box 
    }; 

    this.removeSelected = function() { 
     this.allItems.removeAll(this.selectedItems()); 
     this.selectedItems([]); // Clear selection 
    }; 

    this.sortItems = function() { 
     this.allItems.sort(); 
    }; 
}; 

ko.applyBindings(new BetterListModel()); 

나는 다음과 같은 코드를 일치하도록 clojurescript에서 무엇을 할 수 있는지 확실하지 않다 : this.allItems.push(this.itemToAdd())

의견이 있으십니까?

+0

Keming Labs에서 내부적으로 사용하고있는 Knockout.js에서 영감을 얻은 Compute-Observables 라이브러리를 한 달 간 열어두면 공개됩니다. 나의 Github (@lynaghk)을 주시하십시오. –

+0

감사합니다. 케빈! 나는 정말로 도서관을 가지고 노는 것을 고대하고있다. 그러나 clojure에는없는 다른 내부 변수에 액세스하는 변수를 선언하는 것과 비슷한 유형의 문제가있는 너무 많은 훌륭한 자바 스크립트 라이브러리가 있습니다. js와 clj 사이를 보간하는 명확한 방법이 중요하다는 생각이 듭니다. clojurescript ande javascript를 사용할수록 js 라이브러리가 눈에 띄지 않게됩니다 ... clojure를 배운 후에 연결 만 보았습니다. 어쨌든, 내 대답에 대한 귀하의 의견을 아래에 – zcaudate

+0

잡아 주길 바래 http://fluentsoftware.github.com/cljs-binding/, 노크 아웃으로 성숙하지,하지만 .. – edtsech

답변

5

시행 착오를 많이 후, 나는 clojurescript에 대한 동일한 구조 등을하는 방법을 알아 냈어 자바 스크립트.

this-as 매크로는 몇 가지 특질을 가지고 있으며, 단지 방법은 내가 자바 스크립트에서 다음과 같습니다 뭔가 만들려면 예를 들어, 클래스

에 투입 될 때 작동합니다

var anobj = {a: 9, 
      get_a: function(){return this.a;}}; 

I가이를

(def anobj (js-obj)) 
(def get_a (fn [] (this-as me (.-a me)))) 
(aset anobj "a" 9) 
(aset anobj "get_a" get_a) 

cloj만큼 아름다운 언어에 대해 심각하게 못생긴 : clojurescript에서 동일한 개체를 얻을 수있는 훨씬 더 코딩을 할 ure. 녹아웃에서 일어나는 것과 같이 서로 연결되는 기능이있을 때 상황이 악화됩니다.

this이 많이있는 js- 개체를 만드는 가장 좋은 방법은 __init__ 메서드를 정의하고 클래스에 추가 한 다음 실행 한 다음 클래스에서 제거하는 것입니다. 예를 들어, 나는 다른 객체를 만들고 싶었다 경우 :

와 clojurescript로 작성하고 __init__ 방법은 다음과 같습니다
var avobj = {a: this, 
      b: 98, 
      c: this.a 
      get_a: function(){return str(this.a) + str(this.c);}}; 

: 자바 스크립트보다 왕창 더 많은 코드가 ... 거기에 여전히

(def avobj (js-obj)) 
(def av__init__ 
    #(this-as this 
     (aset this "a" this) 
     (aset this "b" 9) 
     (aset this "c" (.-a this)) 
     (aset this "get_a" (fn [] (str (.-a this) (.-c this)))))) 
(aset avobj "__init__" av__init__) 
(. avobj __init__) 
(js-delete stuff "__init__") 

하지만, 가장 중요한 것은 자바 스크립트와 같은 객체를 얻는 것입니다. 이 양식을 사용하여 모든 변수를 설정하면 매크로를 사용하여 단순화 할 수 있습니다. 이제 매크로를 정의했습니다 :

(defmacro defvar [name & body] 
    (list 'do 
    (list 'def name 
     (list 'map->js 
     { 
      :__init__ 
      (list 'fn [] 
       (list 'this-as 'this 
       (list 'aset 'this "a" "blah")))   
     })) 
    ;(. js/console log ~name) 
    (list '. name '__init__) 
    (list 'js-delete name "__init__"))) 

및 jayq에서 가져온 map-> js.유틸 :

(defvar avobj 
    a this 
    b 9 
    c (.-a this) 
    get_a (fn [] (str (.-a this) (.-c this)))) 

을하고 대답을 녹아웃 :

(defn map->js [m] 
    (let [out (js-obj)] 
    (doseq [[k v] m] 
     (aset out (name k) v)) 
    out)) 

지금 나는이 같은 코드를 작성할 수 있습니다 나를 위해 정말 좋은

(defvar name_model 
    first_name (observable "My") 
    last_name (observable "Name") 
    name (computed (fn [] (str (. this first_name) " " (. this last_name))))) 

(. js/ko (applyBindings name_model)); 

는 자바 스크립트를 정말 잘 일치로 그리고 그것의 전적으로 읽을 수있는!