events - Backbone.js : change not firing on model. 更改()

标签 events backbone.js

我在 Backbone.js 上遇到“更改事件未触发”问题 =/

这是我对用户模型的看法:

    window.UserView = Backbone.View.extend({

        ...

        initialize: function()
        {
            this.model.on('destroy', this.remove, this);

            this.model.on('change', function()
            {
               console.log('foo');
            });
        },

        render: function(selected)
        {
            var view = this.template(this.model.toJSON());

            $(this.el).html(view);

            return this;
        },

        transfer: function(e)
        {                
            var cas = listofcas;

            var transferTo = Users.getByCid('c1');
            var transferToCas = transferTo.get('cas');

            this.model.set('cas', cas);
            console.log('current model');
            console.log(this.model);

            //this.model.change();
            this.model.trigger("change:cas");
            console.log('trigger change');

            transferTo.set('cas', transferToCas);
            console.log('transferto model');
            console.log(transferTo);

            //transferTo.change();
            transferTo.trigger("change:cas");
            console.log('trigger change');

        }

    });

这里是用户模型:

window.User = Backbone.Model.extend({

        urlRoot: $('#pilote-manager-app').attr('data-src'),

        initialize: function()
        {
            this.set('rand', 1);
            this.set('specialite', this.get('sfGuardUser').specialite);
            this.set('name', this.get('sfGuardUser').first_name + ' ' + this.get('sfGuardUser').last_name);
            this.set('userid', this.get('sfGuardUser').id);
            this.set('avatarsrc', this.get('sfGuardUser').avatarsrc);
            this.set('cas', new Array());

            if (undefined != this.get('sfGuardUser').SignalisationBouclePorteur) {

                var cas = new Array();

                _.each(this.get('sfGuardUser').SignalisationBouclePorteur, function(value)
                {
                    cas.push(value.Signalisation);
                });

                this.set('cas', cas);

            }
        }
    });

在用户模型中,有一个“cas”属性,它是一个对象数组。

我在其他主题中读到,如果属性不是值,则更改事件不会在 model.set 上触发。

因此,我尝试使用 model.change() 方法直接触发更改事件。 但是,我的控制台中没有“foo”日志......

最佳答案

我对 Backbone 还很陌生,我也遇到了同样的问题。

经过一些研究,我发现了一些帖子,可以更清楚地说明为什么会发生这种情况,最终事情开始变得有意义:

Question 1

Question 2

核心原因与引用相等与集合/成员相等的概念有关。看来,在很大程度上,引用相等是 Backbone 用来确定属性何时发生更改的主要技术之一。

我发现,如果我使用生成新引用的技术(例如 Array.slice() 或 _.clone()),则可以识别更改事件。

例如,以下代码不会触发该事件,因为我正在更改相同的数组引用:

this.collection.each(function (caseFileModel) {
    var labelArray = caseFileModel.get("labels");
    labelArray.push({ Key: 1, DisplayValue: messageData });
    caseFileModel.set({ "labels": labelArray });
});

虽然此代码确实触发了事件:

this.collection.each(function (caseFileModel) {
    var labelArray = _.clone(caseFileModel.get("labels")); // The clone() call ensures we get a new array reference - a requirement for the change event
    labelArray.push({ Key: 1, DisplayValue: messageData });
    caseFileModel.set({ "labels": labelArray });
});

注意:根据Underscore API , _.clone() 通过引用复制某些嵌套项。不过,根/父对象是克隆的,因此它对于 Backbone 来说可以很好地工作。也就是说,如果您的数组非常简单并且没有嵌套结构,例如[1,2,3]。

虽然我上面改进的代码触发了更改事件,但以下代码没有触发,因为我的数组包含嵌套对象:

var labelArray = _.clone(this.model.get("labels"));
_.each(labelArray, function (label) {
    label.isSelected = (_.isEqual(label, selectedLabel));
});
this.model.set({ "labels": labelArray });

现在为什么这很重要?经过仔细调试后,我注意到在迭代器中我引用了存储的相同对象引用主干。换句话说,我无意中触及了模型的内部并发生了一些翻转。当我调用 setLabels() 时,backbone 正确地识别出没有任何变化,因为它已经知道我翻转了那一点。

在环顾四周之后,人们似乎普遍认为 JavaScript 中的深度复制操作确实很痛苦——没有内置的东西可以做到这一点。所以我这样做了,这对我来说效果很好 - 一般适用性可能会有所不同:

var labelArray = JSON.parse(JSON.stringify(this.model.get("labels")));
_.each(labelArray, function (label) {
    label.isSelected = (_.isEqual(label, selectedLabel));
});
this.model.set({ "labels": labelArray });

关于events - Backbone.js : change not firing on model. 更改(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9909799/

相关文章:

javascript - 主干模型 : nested data structure

javascript - 当 DIV 悬停时文本框失去焦点

jquery - 无法取消绑定(bind)到 $(document) 的事件

python - wxPython:在程序启动时自动执行事件函数

c# - 尝试触发事件时出现 NullReferenceException

javascript - Backbone.js 使用 el 不起作用,但使用 $ ('selector' ) 可以。为什么?

c# - 调用异步方法与事件

javascript - 在下拉菜单中输入字符时,它会从选项中选择任何随机匹配项并触发更改事件

javascript - Backbonejs 在保存成功处理程序中获取 View

events - 在一个元素上 Backbone 多个 View