我正在开发一个jQuery Backbone.js Web应用程序 就像在Adobe Flex中一样,我在我的应用程序中实现了双向数据绑定 输入元素/小部件。 因此,每个输入元素/小部件都知道其对应的模型和模型属性名称 当用户点击标签或输入时,字段值将自动提供给模型。
container.model.set(this.attrName, this.value, options); // command 1
在另一个方向,当模型从后端更新时,视图 输入元素/小部件应该自动获取 更新:
container.model.bind("change:"+ this.attrName, this.updateView, this); // command 2
问题是:
当用户点击进入并且模型自动更新时,“更改:abc”也是
触发和调用this.updateView,不仅在新模型来自时也是如此
后端。
直到现在我的解决方案是在用户按下enter(命令1)时设置模型值时传递选项“source:gui”,并在我的updateView方法中检查它。但我不再满足于这个解决方案了。
有人有更好的解决方案吗? 非常感谢提前 沃尔夫冈
更新:
当传递选项silent:true时,不会调用模型的validate方法,因此
这没有用。参见Backbone.js source 0.9.2:
_validate: function(attrs, options) {
if (options.silent || !this.validate) return true;
答案 0 :(得分:7)
来自Backbone.js网站:
除非{silent:true}作为选项传递
,否则将触发“更改”事件
options.silent = true;
container.model.set(this.attrName, this.value, options);
<强>更新强> 您在问题中添加了新评论,因此我只是补充了我的答案,以修复您提到的新用例(验证流程):
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'});
答案 1 :(得分:6)
双向绑定仅表示:
Backbone没有&#34;烘焙&#34;实现2选项(虽然你当然可以使用事件监听器)
在Backbone中,我们可以通过绑定视图&#34;渲染&#34;轻松实现选项1。其模型的方法&#34;变更&#34;事件。要实现选项2,您还需要向input元素添加更改侦听器,并在处理程序中调用model.set。
检查(jsfiddle.net/sunnysm/Xm5eH/16)js示例,在Backbone中设置双向绑定。
答案 2 :(得分:2)
Backbone.ModelBinder
插件非常适合在Backbone Views和Models之间提供双向数据绑定。我写了一篇博文,内容涵盖了这个插件的一些基本功能。这是直接链接:http://niki4810.github.io/blog/2013/03/02/new-post/
答案 3 :(得分: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:manual
我使用了这样做的库,例如Epoxy.js(仅缩小了11k)。此外还有其他几个,我建议在使用上面的概念证明代码之前很久。
我会对上面的TwoWayBoundView类可能产生的潜在陷阱和改进感兴趣(但 没有 超出基本的双向绑定请!即我是 不 寻找要添加的更多功能。)