2012-09-26 126 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类以上(但没有超越了基本的双向绑定,请进行潜在的缺陷和改进!也就是我寻找更多的功能添加。)