问题 backbone.js中的双向数据绑定


我正在开发一个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源代码0.9.2:

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

4908
2017-09-26 15:08


起源



答案:


来自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'});

7
2017-09-26 15:29



谢谢Daniel。但是使用此选项,不会调用“validate”。所以它对我没有帮助。 - Wolfgang Adamec
嗨沃尔夫冈,我看到了你的新更新,并添加了一个解决方案。 =) - Daniel Aranda


答案:


来自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'});

7
2017-09-26 15:29



谢谢Daniel。但是使用此选项,不会调用“validate”。所以它对我没有帮助。 - Wolfgang Adamec
嗨沃尔夫冈,我看到了你的新更新,并添加了一个解决方案。 =) - Daniel Aranda


双向绑定意味着:

  1. 当模型中的属性更新时,UI也会更新。
  2. 当UI元素更新时,更改会传播回 模型。

Backbone没有2个选项的“烘焙”实现(尽管你当然可以使用事件监听器来实现)

在Backbone中,我们可以通过将视图的“render”方法绑定到其模型的“change”事件来轻松实现选项1。要实现选项2,您还需要向input元素添加更改侦听器,并在处理程序中调用model.set。

检查(jsfiddle.net/sunnysm/Xm5eH/16)jsfiddle示例,在Backbone中设置双向绑定。


6
2017-09-05 12:31





Backbone.ModelBinder插件非常适合在Backbone Views和Models之间提供双向数据绑定。我写了一篇博文,介绍了这个插件的一些基本功能。这是直接链接: http://niki4810.github.io/blog/2013/03/02/new-post/


2
2018-04-07 21:45





我想看看裸骨代码与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

我已经使用了这样做的库,例如Epoxy.js(仅缩小了11k)。此外还有其他几个,我建议在使用上面的概念验证代码之前很久。

我会对上面的TwoWayBoundView类可能产生的潜在陷阱和改进感兴趣(但是 没有超越基本的双向约束请!即我  寻找更多要添加的功能。)


0
2017-12-16 21:29