2012-09-26 280 views
11

我正在開發一個jQuery Backbone.js Web應用程序。
就像在Adobe Flex中一樣,我在我的應用中爲輸入元素/小部件實現了2路數據綁定。因此,每個輸入元素/控件都知道其對應的模型和模型屬性名稱。
當用戶點擊標籤頁或輸入時,字段值會自動提供給模型。backbone.js中的雙向數據綁定

container.model.set(this.attrName, this.value, options); // command 1 

在另一個方向上,當模型被從後端更新時, 輸入元件的視圖/插件自動地獲得 更新:

container.model.bind("change:"+ this.attrName, this.updateView, this); // command 2 

的問題是:
當用戶點擊輸入並且模型自動更新,並且觸發「change:abc」並且調用this.updateView,不僅當來自 後端的新模型被調用時。

我的解決方案到現在爲了在用戶按下輸入(命令1)時設置模型值並在我的updateView方法中檢查該選項時傳遞選項「source:gui」。但是我不再滿足於這個解決方案。

有沒有人有更好的解決方案? 非常感謝提前
沃爾夫岡

更新:
當沉默的選項:真正的通過,該模型的驗證方法不叫,所以 沒有幫助。見Backbone.js的來源0.9.2:

_validate: function(attrs, options) { 
    if (options.silent || !this.validate) return true; 

回答

7

從Backbone.js的網站:

A 「改變」 事件將被觸發,除非{沉默:真正}作爲一個選項傳遞

options.silent = true; 
container.model.set(this.attrName, this.value, options); 

更新: 您添加到您的問題,新的評論,所以我只是補充,我的答案來解決新的使用CAS你提到E(驗證流程):

var ExtendedModel = Backbone.Model.extend({ 
    uiChange : false, 
    uiSet: function (attributes, options, optional) { 
     this.uiChange = true; 
     this.set(attributes, options, optional); 
     this.uiChange = false; 
    } 
}); 

var MyModel = ExtendedModel.extend({ 
}); 

var model = new MyModel(); 
model.on('change:name', function(){ 
    console.log('this.uiChange: ', this.uiChange); 
}); 

//simulates the server side set 
model.set({name:'hello'}); 

//simulates the ui side set you must use it to set from UI 
model.uiSet({name:'hello2'}); 
+0

謝謝丹尼爾。但是通過這個選項,「驗證」不會被調用。所以它不能幫助我。 –

+0

嗨沃爾夫岡,我看到了你的新更新並添加了一個解決方案。 =) –

6

雙向綁定只是表示:

  1. 當模特屬性得到更新,這樣做的UI。
  2. 當UI元素得到更新時,所做的更改會傳播回 模型。

骨幹沒有「出爐,在」實施2選項

在骨幹網(雖然你可以使用事件偵聽器當然做到這一點),我們可以很容易地通過結合視圖的「實現選項1渲染「方法到其模型的」更改「事件。要實現選項2,還需要將更改偵聽器添加到輸入元素,並在處理程序中調用model.set。

檢查(jsfiddle.net/sunnysm/Xm5eH/16)jsfiddle在Backbone中設置了雙向綁定的示例。

0

我想看看裸骨代碼與Backbone.js的雙向綁定是什麼。這是我想出了:

var TwoWayBoundView = Backbone.View.extend({ 
    initialize: function(options) { 
     this.options = _.defaults(options || {}, this.options); 
     _.bindAll(this, "render"); 
     this.model.on("change", this.render, this); 
     this.render(); 
    }, 

    events: { 
     "change input,textarea,select": "update" 
    }, 

    // input updated 
    update: function(e) { 
     this.model.set(e.currentTarget.id, $(e.currentTarget).val()); 
    }, 

    // model updated...re-render 
    render: function(e) { 
     if (e){ 
      var id = Object.keys(e.changed)[0]; 
      $('#'+id).val(e.changed[id]); 
     } 
     else{ 
      _.each(this.model.attributes, function(value, key){ 
       $('#'+key).val(value); 
      }); 
     } 
    } 
}); 

和使用:

var model = new Backbone.Model({ prop1: "uno 1", prop2: "dos 2", prop3: "3" }); 
var view = new TwoWayBoundView({ 
    el: "#myContainer", 
    model: model 
}); 

這裏有一個jsbin它:我用的是做到這一點的庫,例如環氧http://jsbin.com/guvusal/edit?html,js,console,output

。 JS(只有11K縮小)。除此之外還有其他幾種,在使用上面的概念證明代碼之前我會建議很久。

我有興趣,可以與TwoWayBoundView類以上(但沒有超越了基本的雙向綁定,請進行潛在的缺陷和改進!也就是我尋找更多的功能添加。)