Backbone.js的:不改变射击model.change() [英] Backbone.js : change not firing on model.change()

查看:113
本文介绍了Backbone.js的:不改变射击model.change()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在面临的Backbone.js的= /

I'm facing a "change event not firing" issue on Backbone.js =/

下面我的用户模型视图:

Here my view of User model :

    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');

        }

    });

在这里,用户模型:

Here, the User model :

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属性,它是对象的数组。

In User model, there is "cas" attribute, which is an array of objects.

我在别人的主题,更改事件不火的model.set阅读,如果属性不是一个值。

I read in others topics that change events are not fire on model.set if attributes are not a value.

所以,我尝试直接触发与model.change()方法的改变事件。
但是,我没有富在日志中我的控制台...

So, I try to trigger directly the change event with model.change() method. But, I have no "foo" log in my console ...

推荐答案

我是pretty新的骨干和我有同样的问题。

I'm pretty new to backbone and I was having this same problem.

之后做一些研究,我发现,能够解释为什么这是发生一点点光,最后几个职位,事情开始变得有意义:

After doing some research, I found a few posts that shed a little bit more light on why this was happening, and eventually things started to make sense:

问题1

<一个href=\"http://stackoverflow.com/questions/8491546/models-change-event-wont-fire-when-updating-an-array\">Question 2

最核心的原因有参考平等与集/成员平等的观念有关。看来,在很大程度上,参考平等是主要的技术骨干网使用弄清楚当属性发生了变化之一。

The core reason has to do with the notion of reference equality versus set/member equality. It appears that to a large extent, reference equality is one of the primary techniques backbone uses to figure out when an attribute has changed.

我觉得,如果我使用可产生类似Array.slice()或_.clone()一个新的参考技术,改变事件被识别。

I find that if I use techniques that generate a new reference like Array.slice() or _.clone(), the change event is recognized.

所以,举例来说,下面的code不会因为我改变了相同的数组引用触发事件:

So for example, the following code does not trigger the event because I'm altering the same array reference:

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

虽然这code确实触发事件:

While this code does trigger the event:

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 });
});

请注意:根据href=\"http://underscorejs.org/#clone\">参照下划线API ,_.clone()副本的某些嵌套项目的

NOTE: According to the Underscore API, _.clone() copies certain nested items by reference. The root/parent object is cloned though, so it will work fine for backbone. That is, if your array is very simple and does not have nested structures e.g. [1, 2, 3].

虽然上面我提高code触发change事件,下面并没有因为我的数组包含嵌套对象:

While my improved code above triggered the change event, the following did not because my array contained nested objects:

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

现在为什么这件事情?非常精心调试后,我注意到,在我的迭代器,我引用相同的对象引用骨干被存储。换句话说,我无意中把手伸进我的模型的内部结构,并翻转了一下。当我打电话setLabels(),骨干正确地认识到,什么都没有改变,因为它已经知道的我翻了一下。

Now why does this matter? After debugging very carefully, I noticed that in my iterator I was referencing the same object reference backbone was storing. In other words, I had inadvertently reached into the innards of my model and flipped a bit. When I called setLabels(), backbone correctly recognized that nothing changed because it already knew I flipped that bit.

看着周围一些之后,人们似乎普遍说深拷贝操作在JavaScript中是一个真正的痛苦 - 没有内置做到这一点。所以,我这样做,这对我来说工作得很好 - 普遍适用性可能会有所不同:

After looking around some more, people seem to generally say that deep copy operations in javascript are a real pain - nothing built-in to do it. So I did this, which worked fine for me - general applicability may vary:

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

这篇关于Backbone.js的:不改变射击model.change()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆