嵌套在 firebase 集合模型中的集合没有添加功能

2023-12-29

在我的应用程序中,我尝试使用 Firebase 来存储基于骨干框架的实时数据。

问题是这样的:
我有一个子级别的模型和集合,它们都是通用骨干模型和集合。

var Todo = Backbone.Model.extend({
    defaults: { 
        title: "New Todo",
        completed : true
    }
});

var Todocollection = Backbone.Collection.extend({
    model: Todo,
    initialize: function() {
        console.log("creating a todo collection...");
    },
});

然后是一个高级模型,其中包含子级集合作为属性。

var Daymodel = Backbone.Model.extend({
    defaults : {
        day: 1,
        agenda : new Todocollection()
    }
});

然后对于更高级别的集合,我将 firebase 集合

var DayCollection = Backbone.Firebase.Collection.extend({
    model: Daymodel
});

到目前为止,我可以正确地将数据添加到更高级别的集合,其中有一个day属性和一个agenda属性(应该是TodoCollection).

问题是当我尝试将数据添加到子级别集合时,它无法正常工作。

this.collection.last()
    .get("agenda")
    .add({
        title: this.input.val(), 
        completed: false
    });

上面的代码将位于 View 部分内。和this.collection.last()将得到最后一个模型。get("agenda")应该是集合对象。

但这行不通。该错误表明this.collection.last(...).get(...).add不是一个函数。

经过调试我发现this.collection.last().get("agenda")返回一个通用的 JS 对象而不是集合对象。

我进一步调试,如果我使用主干集合作为外部集合DayCollection。一切都能顺利进行。

如何解决这样的问题呢?


为什么默认集合属性不再是集合?

当您获取或创建新的Daymodel我认为看起来像这样:

{
    day: 1,
    agenda : [{
        title: "New Todo",
        completed : false
    }, {
        title: "other Todo",
        completed : false
    }]
}

默认agenda属性是Todocollection首先被原始对象数组替换。骨干不知道这个agenda是一个集合,不会自动填充它。

这就是 Backbone 所做的defaults创建模型时(第 401 行) https://github.com/jashkenas/backbone/blob/8ec88604732944f197b352a6be22c8216ea9d3a1/backbone.js#L401:

var defaults = _.result(this, 'defaults');
attrs = _.defaults(_.extend({}, defaults, attrs), defaults);
this.set(attrs, options);

_.extend({}, defaults, attrs)defaults首先,但随后,它们被过去的覆盖attrs.

如何在模型中使用集合?

以下是实现此目的的三种解决方案。仅使用其中之一,或根据以下内容创建您自己的。

最简单、最有效的方法是don't.

保持Todocollection出于Daymodel模型并仅在需要时创建集合,就像在假想 DayView:

var DayView = Backbone.View.extend({
    initialize: function() {
        // create the collection in the view directly
        this.agenda = new Todocollection(this.model.get('agenda'));
    },
    /* ...snip... */
});

然后,当您想要在模型中保留更改时,只需将集合模型放回到Daymodel:

this.model.set('agenda', this.collection.toJSON());

将集合放入模型的属性中

您可以创建一个函数来延迟创建集合并将其作为属性保留在模型中,而不是属性,离开attributes哈希干净.

var Daymodel = Backbone.Model.extend({
    defaults: { day: 1, },
    getAgenda: function() {
        if (!this.agenda) this.agenda = new Todocollection(this.get('agenda'));
        return this.agenda;
    }
});

然后,模型控制该集合,并且可以轻松地与已共享该模型的所有内容共享该集合,每个实例仅创建一个集合。

保存模型时,您仍然需要将原始模型传回attributes hash.

属性内的集合

您可以通过小的改变来完成您已经尝试做的事情。

  1. 切勿将物体放入defaults

    ...而不使用返回对象的函数。

    var Daymodel = Backbone.Model.extend({
        defaults: function() {
            return {
                day: 1,
                agenda: new Todocollection()
            };
        },
    });
    

    否则,agenda集合将在每个实例之间共享Daymodel因为集合在创建时只创建一次Daymodel class.

    这也适用于对象文字、数组、函数(为什么你要把它放在defaults反正?!)。

  2. 确保它始终是一个集合。

    var Daymodel = Backbone.Model.extend({
        defaults: { day: 1, },
        initialize: function(attrs, options) {
            var agenda = this.getAgenda();
            if (!(agenda instanceof Todocollection)) {
                // you probably don't want a 'change' event here, so silent it is.
                return this.set('agenda', new Todocollection(agenda), { silent: true });
            }
        },
        /**
         * Parse can overwrite attributes, so you must ensure it's a collection
         * here as well.
         */
        parse: function(response) {
            if (_.has(response, 'agenda')) {
                response.agenda = new Todocollection(response.agenda);
            }
            return response;
        },
        getAgenda: function() {
            return this.get('agenda');
        },
        setAgenda: function(models, options) {
            return this.getAgenda().set(models, options);
        },
    });
    
  3. 确保它是可序列化的。

    var Daymodel = Backbone.Model.extend({
        /* ...snip... */
        toJSON: function(options) {
            var attrs = Daymodel.__super__.toJSON.apply(this, arguments),
                agenda = attrs.agenda;
            if (agenda) {
                attrs.agenda = agenda.toJSON(options);
            }
            return attrs;
        },
    });
    

    如果您将集合放入模型属性中,如上所述,这可以很容易地应用。

  4. 避免意外覆盖agenda属性。

    这与第 2 点是一致的,这就是它变得困难的地方,因为它很容易被忽视,或者其他人(或另一个库)可以在以后做到这一点。

    可以覆盖save and set函数来添加检查,但从长远来看它变得过于复杂而没有太多好处。

模型中的集合有什么缺点?

我谈到了在模型中完全避免它,或者懒惰地创建它。这是因为如果实例化大量模型,它会变得非常慢;如果每个模型嵌套多次(具有模型集合的模型,具有其他模型集合的模型等),它会变得非常慢。

按需创建时,您仅在需要时使用计算机资源,并且仅用于所需的内容。例如,任何现在不在屏幕上的模型都不会创建其集合。

开箱即用的解决方案

也许要使其正常工作需要做太多工作,因此完整的解决方案可能会有所帮助,并且有几个。

  • 骨干关系 http://backbonerelational.org/
  • 主干嵌套 https://github.com/afeld/backbone-nested
  • 主干嵌套模型 https://github.com/blittle/backbone-nested-models
  • 主干深度模型 https://github.com/kahwee/backbone-deep-model
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

嵌套在 firebase 集合模型中的集合没有添加功能 的相关文章

随机推荐

  • 通过 SOS 调查 CLR

    目前 我正在深入研究 CLR 并尝试找到托管对象的适当大小 我有两种简单的类型 XClass class XClass public XStruct StructField new XStruct public int IntField p
  • 为什么在 javascript 中列出类的实际构造函数很重要

    我正在阅读 javascript 花园http bonsaiden github com JavaScript Garden http bonsaiden github com JavaScript Garden 关于 javascript
  • 为什么我的 OBJ 解析器渲染网格是这样的?

    我自己决定将 OBJ 解析器 导入器支持添加到我一直在开发的 3D 渲染引擎中 我已遵循规范在这里找到 http www martinreddy net gfx 3d OBJ spec几乎 到了发球台 除了当前限制对组 面 顶点 法线和纹理
  • IllegalStateException:PWC3990:已为此响应调用 getWriter()

    java lang IllegalStateException PWC3990 getWriter has already been called for this response 如何解决这个错误 我运行一个简单的 servlet 代码
  • 如何使用 FirefoxProfile 或 FirefoxOptions 通过 Selenium 设置 Firefox 浏览器的窗口位置

    我需要通过创建驱动程序来更改 Firefox 窗口的位置 driver webdriver Firefox 我知道创建驱动程序后可以更改窗口位置 driver set window position 我不知道如何使用 Firefox 配置文
  • 如何读取.net中的SQL Server架构信息?

    我如何在 C 中知道数据库中的表列表 每个表具有完整规范的列列表 例如第一列是 Id 其数据类型为 int 50 等 Use the 获取模式 http msdn microsoft com en us library ms136366 a
  • 全新安装后 EKEventStore.calendars 始终为空

    我的 iOS 应用程序有一个奇怪的问题 在全新安装后 如果我尝试添加日历事件 在接受本机日历权限提示后 我的 eventStore 单例永远不会显示任何可用的日历 并且defaultCalendarForNewEvents总是nil 我尝试
  • jquery中如何将密码转换成md5? [复制]

    这个问题在这里已经有答案了 实际上我正在创建更改密码页面 这是我检查旧密码是否与现有密码匹配的功能 该密码存储在数据库中的 MD5 中 因此我想首先将该密码转换为 MD5 然后我可以检查该密码 这是代码 function fnIsValid
  • iOS“当前图形上下文”-那是什么

    当我绘制线条和形状等时 我会在 iOS 中获得 当前图形上下文 到底什么是 当前图形上下文 我正在寻找 30 000 英尺的描述 现在我只是复制并粘贴 UI 代码 不太确定它在做什么 图形上下文是存储有关绘图状态的信息的地方 这包括填充颜色
  • C# MVC 从 S3 异步下载大文件

    我必须从 aws S3 async 下载文件 我有一个锚标记 单击它时 将在控制器中点击一个方法以供下载 该文件应该在浏览器底部开始下载 就像其他文件下载一样 In View a href controller action paramet
  • HTML PDF 查看器

    除了使用 Acrobat Reader 之外 还有其他方法可以在网络上查看 PDF 文件吗 我需要控制查看器以编程方式触发文档的打印 PDF 的来源应来自网络服务 URL AspX 我认为最简单的方法是使用 Google Doc Viewe
  • 使用显式类型初始化 ImmutableMap? [复制]

    这个问题在这里已经有答案了 我需要初始化一个 ImmutableMap guava 21 0 并且我需要它解析为一个 Map gt 对于这个例子 我将只使用 String 所以我有 import com google common coll
  • 如何使用 Python 获取带有 Selenium 的

    我正在使用 Selenium WebDriver 使用 Python 进行 UI 测试 我想检查以下 HTML ul li Something here li li And here li li Even more here li ul 我
  • Java JDBC - 如何使用 tnsnames.ora 连接到 Oracle

    tnsnames ora文件包含Databases以及它们的描述 host port 是否可以依赖上述文件建立连接 仅提供数据库名称 为了找到这个文件 我必须知道默认的 oracle 主目录 我需要在 Windows 注册表中检查HKEY
  • 带子边距的 Div 高度

    我有 2 个 div 我想让它们的高度相等 var highestCol SecondColumn height column first height highestCol 我知道第二个 div 总是高于第一个 div 当两个 div 中
  • 如何将 Phillips Hue 灯泡的 RGB 值转换为 XY 值

    如何正确地将我拍摄的图片中的像素 RGB 值转换为发送到 Phillips Hue 设备所需的 XY 值 我当前的代码执行以下操作 1 拍一张照片 找出最常见的颜色 2 循环扔它们 然后再拍一张照片 3 将值发送到 Phillips Hue
  • 正则表达式匹配 html 标签之外的文本,而不是特定标签之间的文本

    我试图获得一个正则表达式来匹配 html 标签外部和之间的一些单词 而不是标签本身 但我还需要在它们位于 html 标题标签 h1 h2 h3 等 之间时排除它们 这是我尝试过的 bword b gt lt i 实例 https regex
  • 等待多重未来?

    我想运行相同类型的任务 工作线程 但一次不超过一定数量的任务 当任务完成时 其结果是新任务的输入 然后可以启动该新任务 有没有什么好的方法可以在 C 11 中使用异步 未来范例来实现这一点 乍一看 它看起来很简单 您只需使用以下命令生成多个
  • 在 package.json 中使用私有 git 存储库部署 Google App Engine

    我的 package json 依赖于私有 Bitbucket 存储库 my dependency git ssh email protected cdn cgi l email protection something my depend
  • 嵌套在 firebase 集合模型中的集合没有添加功能

    在我的应用程序中 我尝试使用 Firebase 来存储基于骨干框架的实时数据 问题是这样的 我有一个子级别的模型和集合 它们都是通用骨干模型和集合 var Todo Backbone Model extend defaults title