13

我正在开发一个 jQuery Backbone.js Web 应用程序。
正如在 Adob​​e Flex 中一样,我在我的应用程序中为输入元素/小部件实现了 2 路数据绑定。因此,每个输入元素/小部件都知道其对应的模型和模型属性名称。
当用户点击 tab 或 enter 时,字段值会自动提供给模型。

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,而不仅仅是当新模型来自后端时。

到目前为止,我的解决方案是在用户按下 enter(命令 1)时设置模型值时传递一个选项“source:gui”,并在我的 updateView 方法中检查它。但我不再满足于这个解决方案。

有人有更好的解决方案吗?非常感谢
沃尔夫冈

Update:
When the option silent: true is passed, the validate method of the model is not called, so that does not help. 请参阅 Backbone.js 源 0.9.2:

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

4 回答 4

8

从 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'});
于 2012-09-26T15:29:02.583 回答
6

双向绑定只是意味着:

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

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

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

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

于 2015-09-05T12:31:37.860 回答
2

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

于 2013-04-07T21:45:12.300 回答
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

我使用了执行此操作的库,例如 Epoxy.js(仅缩小了 11k)。除此之外,还有其他几个,我会在使用上面的概念证明代码之前很久就推荐它们。

我会对上面的 TwoWayBoundView 类可能带来的潜在缺陷和改进感兴趣(但除了基本的双向绑定之外,别无所求!即我不是在寻找要添加的更多功能。)

于 2016-12-16T21:29:50.923 回答