Backbone.js:更改未在 model.change() 上触发

2024-01-17

我在 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”日志......


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

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

问题1 https://stackoverflow.com/questions/7325004/backbone-js-set-model-array-property

问题2 https://stackoverflow.com/questions/8491546/models-change-event-wont-fire-when-updating-an-array

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

我发现如果我使用生成新引用的技术(例如 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 });
});

注:根据下划线API http://underscorejs.org/#clone, _.clone() 通过引用复制某些嵌套项。不过,根/父对象是克隆的,因此它对于骨干网来说可以很好地工作。也就是说,如果您的数组非常简单并且没有嵌套结构,例如[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 正确地识别出没有任何变化,因为它已经knew我翻转了一点。

环顾四周后,人们似乎普遍认为 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 });
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Backbone.js:更改未在 model.change() 上触发 的相关文章

随机推荐

  • 如何在 Chakra UI 元素中添加 ::-webkit-scrollbar 伪元素? (反应)

    我正在使用 Chakra UI 我需要使用 css 伪元素自定义滚动条样式 webkit scrollbar 但是 Chakra UI 没有看到这个伪元素 并且我不知道在哪里可以在不创建全局 css 类的情况下设置这个特定组件的样式 这是我
  • HTTP 与 HTTPS 性能

    http 和 https 之间的性能有什么重大差异吗 我似乎记得读到过 HTTPS 的速度是 HTTP 的五分之一 这对于当前一代网络服务器 浏览器有效吗 如果是的话 有任何白皮书支持吗 对此有一个非常简单的答案 分析您的 Web 服务器的
  • 如何从文本中提取命名实体+动词

    嗯 我的目标是从文本中提取 NE 人 和与其相关的动词 例如 我有这样的文字 邓布利多转身沿着街道走回去 哈利 波特在毯子里翻了个身 没有醒来 作为理想的结果我应该得到 邓布利多转身走了 哈利 波特卷起 我使用斯坦福 NER 来查找和标记人
  • Angular 5 与 Canvas drawImage 未显示

    尝试使用drawImage 将背景图像添加到画布 但它没有显示 我知道图像的路径是正确的 因为我可以 img src 那行得通 其他一切在 JavaScript 中都可以正常工作 但不能很好地转换为 Angular HTML
  • 使用 Jquery 删除 CSS 属性

    我发现的所有其他答案仅删除属性的设置 而不是完全删除属性 我正在将元素从绝对定位更改为固定定位 我需要删除 right 定位属性并将其替换为 margin right 以便该元素位于其父 DIV 内的右侧 如果没有删除 right 属性 该
  • 加盐和哈希,为什么不使用用户名?

    我必须承认我对大多数与 Web 应用程序相关的高科技安全问题一无所知 但我至少认为我可以问一件事 因为这是一个直接的问题 并且 希望 有具体的答案 以这个网站为例 http www 15seconds com issue 000217 ht
  • 如何在 macOS 上使用终端重新启动 android adb?

    我一直遇到 Android Studio ADB 无法识别我的设备的问题 到目前为止 我找到的唯一解决方案是完全重新启动整个计算机 但这是不切实际的 我希望能够从终端重新启动 ADB 因为我在这里看到了其他帖子 声称它将解决该问题 但是 我
  • 无法在 HTC One M8 Lollipop 上进行 systrace

    我正在尝试使用systrace来自 Android Studio 的默认设置systrace选项设置 我还没有root手机 HTC Sense v6 0 Android 5 0 1 HTC SDK API 级别 6 55 当我这样做时 我得
  • 如何在Java中生成随机JSON字符串?

    我想测试apache kafka的一个功能 所以我需要用Java生成随机JSON字符串 我的生产数据是JSON格式 我用谷歌搜索 找到了这些网站 如何生成随机字母数字字符串 https stackoverflow com questions
  • 根据滚动隐藏和显示工具栏

    这个问题仅涉及代号一 我需要使 Codename One Form 的工具栏移动 如该视频所示 https www informatica libera net videoLavoro hideShowToolbarOnScrolling
  • 排序日期和时间

    我正在尝试编写一个控制台应用程序来根据开始日期按升序对我的日期和时间进行排序 这是我正在尝试做的一个示例 我的输入 break Start1 15 02 12 12 30PM break End1 15 02 12 01 30PM brea
  • 如何利用 FileReader 的异步特性实现进度条和回调

    我在 for 循环中调用了 FileReader API 以迭代多个文件对象 我使用 FileReader 本质上显示图像的预览 function for var i in Files var fileReader new FileRead
  • 在 .NET 中,如何在不重新压缩 JPEG 的情况下编写 Exif 标头?

    我有一个JPEG http en wikipedia org wiki JPEG我想要设置的图像Exif http en wikipedia org wiki Exchangeable image file format标题 特别是作者 在
  • 限制Spring Boot中的Tomcat只能访问某些IP地址

    我需要将基于 Spring Boot 的应用程序的嵌入式 tomcat 限制为某些 IP 地址 我只想允许来自两个 IP 地址的传入连接 而不是全部 我知道如何在未运行嵌入式的 Tomcat 中执行此操作 但不知道在 Spring Boot
  • 使用 Travis CI 将 Maven 版本部署到 Github

    我成功地使用标签将 JAR 从 Maven 项目部署到了 Github 但是 当前配置假设 JAR 的文件名始终保持不变 但事实并非如此 当我发布新版本时 这将相应更改 因此部署将失败 有没有办法在 YAML 文件中使用通配符 根据我在 S
  • 使用 PouchDB 过滤设计文档

    我正在使用设计文档来确保只有所有者才能修改文档 如何防止 couchdb 复制此设计文档 您可以使用过滤选项 http pouchdb com api html replication in changes and replicate e
  • ZF2:Zend Framework 2 完整 URL(包括主机名)

    在我看来 我需要绘制完整的 URL 像这样 http hostename com default url 当我尝试使用时 this gt url default array 1 2 3 我只得到 index get 有没有任何 Zend 方
  • Carrierwave - 如果文件类型不在白名单上,则触发存在验证

    在我的 Rails 4 应用程序中 我使用 Carrierwave 上传图像 class UserItemImage lt ActiveRecord Base include PicturesHelper attr accessor foo
  • 占位符张量需要机器学习引擎预测中的值,但不需要本地预测

    我一直在开发一个与云 ML 引擎的在线预测服务一起使用的模型 我的模型包含一个placeholder with default我用它来保存预测显着性阈值的张量 threshold tf placeholder with default 0
  • Backbone.js:更改未在 model.change() 上触发

    我在 Backbone js 上面临 更改事件未触发 问题 这是我对用户模型的看法 window UserView Backbone View extend initialize function this model on destroy