2012-06-04 21 views
5

knockout.js dosyasını clojurescript ile sıkıştırmaya çalışıyorum ancak bunun çok zor olacağını düşünüyorum. Benim sahip olduğum problem 'bu' değişkenin referansı. Vazgeçmeyi düşünüyorum ve sadece javascript'i doğrudan kullanıyorum.clojurescript kullanarak knockout.js sarmalanıyor

Sanırım bazı makrolar kolay fonksiyonları sarmak için başardınız http://knockoutjs.com/examples/helloWorld.html ve http://knockoutjs.com/examples/contactsEditor.html

kapalı örnekler aldık. Örneğin:

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); 
}; 

olur:

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

Ancak daha sert gibi bir şey için:

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()); 

ben böyle bir kod eşleşecek şekilde clojurescript neler yapabileceğini emin değilim: this.allItems.push(this.itemToAdd())

Herhangi bir düşünce?

+0

Bir ay boyunca sıkı tutabiliyorsanız, Keming Labs'da dahili olarak kullandığımız Knockout.js-esinlenmiş bilgisayarlı gözlemlenebilir kitaplık kaynaklarından yararlanmaya açık olacağız. Github'a (@lynaghk) göz atın. –

+0

Teşekkürler Kevin! Kütüphaneyle uğraşmayı dört gözle bekliyorum. Bununla birlikte, clojure'nin sahip olmadığı diğer iç değişkenlere erişen değişkenleri bildirme gibi benzer türde problemlere sahip olan çok fazla sayıda javascript kütüphanesi vardır. Ben js ve cljs arasında enterpolasyon için net bir yolu olması önemli olduğunu hissediyorum. Ben clojurescript ande javascript ile oynadığım daha çok, iyi js kütüphanelerinin liseli bir şekilde olduğunu daha fazla buldum ... ki bu sadece clojure'ı öğrendikten sonra bağlantıyı gördüm. Neyse, cevabım hakkındaki yorumlarınızı – zcaudate

+0

'dan almayı umuyoruz. Http://fluentsoftware.github.com/cljs-binding/ adresine bakın, Knockout kadar olgun değil, ama .. – edtsech

cevap

5

deneme yanılma bir sürü sonra clojurescript için aynı yapıya olarak ele geçirmek için ne anladım javascript için.

this-as makro birkaç huyların vardır ve tek yöntem javascript şöyle bir şey yaratmak istiyorum örneğin sınıfta

sokulduğunda çalışır:

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

mecburum

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

cloj kadar güzel bir dil için ciddi çirkin: clojurescript aynı nesneyi almak için bir sürü daha kodlama yapmak obilyaları. Birbirine bağlanan fonksiyonlar olduğunda, işler bittiğinde olduğu gibi kötüleşir.

this ürününün içinde bir js nesnesi oluşturmanın en iyi yolunun, bir __init__ yöntemini tanımlaması, onu sınıfa eklemesi ve sonra da çalıştırması ve ardından sınıfa eklemesi olduğunu buldum. Örneğin, ben başka bir nesneyi yapmak istiyorsa:

ile clojurescript olarak yazılır ve __init__ yöntem şöyle
var avobj = {a: this, 
      b: 98, 
      c: this.a 
      get_a: function(){return str(this.a) + str(this.c);}}; 

: javascript daha bir sürü daha kod ... hala var

(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__") 

ama en önemli şey, javascript ile aynı nesneyi almanızdır. Bu formu kullanarak tüm değişkenleri ayarlamak ayrıca makroların basitleştirilmesini sağlar. Şimdi bir makro tanımladım:

ve map-> js, jayq.utils:

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

ve cevap nakavt:

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

Şimdi böyle bir kod yazabilirsiniz benim için gerçekten güzel

(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)); 

o javascript gerçekten iyi eşleşmeleri olarak ve onun tamamen okunabilir!

İlgili konular