【问题标题】:Persisting & loading metadata in a backbone.js collection在backbone.js 集合中持久化和加载元数据
【发布时间】:2011-08-21 08:58:08
【问题描述】:

我有一个使用backbone.js 的情况,我有一个模型集合,以及一些关于模型的附加信息。例如,假设我要返回一个数量列表:它们有一个与每个模型相关联的数量。现在假设每个数量的单位总是相同的:比如夸脱。那么我从服务中返回的 json 对象可能类似于:

{
    dataPoints: [
         {quantity: 5 },
         {quantity: 10 },
         ...
    ],
    unit : quarts
 }

现在骨干集合没有真正的机制来将这个元数据与集合本地关联,但在这个问题中向我建议:Setting attributes on a collection - backbone js 我可以使用.meta(property, [value]) 样式函数扩展集合 - 这是一个很好的解决方案。但是,很自然地,我们希望能够像上面那样从 json 响应中干净地检索这些数据。

Backbone.js 为我们提供了parse(response) 函数,它允许我们结合url 属性指定从何处提取模型列表的集合。但是,据我所知,如果不重载 fetch(),就无法创建更智能的功能,这会删除部分已经可用的功能。

我的问题是:有没有比重载fetch()(并尝试将其称为超类实现)更好的选择来实现我想要实现的目标?

谢谢

【问题讨论】:

    标签: javascript json collections backbone.js


    【解决方案1】:

    就个人而言,我会将Collection 包装在另一个Model 中,然后覆盖parse,如下所示:

    var DataPointsCollection = Backbone.Collection.extend({ /* etc etc */ });
    var CollectionContainer = Backbone.Model.extend({
        defaults: {
            dataPoints: new DataPointsCollection(),
            unit: "quarts"
        },
        parse: function(obj) {
            // update the inner collection
            this.get("dataPoints").refresh(obj.dataPoints);
    
            // this mightn't be necessary
            delete obj.dataPoints;
    
            return obj;
        }
    });
    

    Collection.refresh() 调用使用新值更新模型。如前所述,将自定义 meta 值传递给 Collection 可能会阻止您绑定到这些元值。

    【讨论】:

    • 我知道这与您在链接的另一篇文章中得到的答案相矛盾,但集合不具备模型的所有属性,例如 parse,以便能够覆盖。如果 Collection 需要元数据具有意义,那么不妨在 Backbone 提供的对象结构中反映这一点,而不是使用 IMO 的 meta-on-collection 解决方案“带外”。
    • 这对我来说似乎很合理。这样做的关键是能够覆盖模型对象和集合上的 parse/url/fetch。非常感谢。
    • 现在不推荐使用 Collection.refresh(),请改用 Collection.reset()。
    • 在您的示例中,CollectionContainer 的所有实例都将共享dataPoints 的同一实例,这可能并不总是可取的。为避免这种情况,请在 initialize 方法中使用 new DataPointsCollection() 初始化 dataPoints 属性。
    【解决方案2】:

    此元数据不属于该集合。它属于代码的名称或其他一些描述符。您的代码应该以声明方式知道它拥有的集合仅包含石英元素。由于 url 指向石英元素,它已经这样做了。

    var quartzCollection = new FooCollection();
    quartzCollection.url = quartzurl;
    quartzCollection.fetch();
    

    如果你真的需要获取这些数据,为什么不直接调用

    _.uniq(quartzCollecion.pluck("unit"))[0];

    【讨论】:

    • 该单位在 AJAX 调用之前是未知的。我不使用pluck,因为它要求我的集合中的每个模型对象都存储单元 - 这导致响应的大小大于仅将其作为元数据关联一次。此外,我怀疑进行这样的操作会产生很大的开销。
    • @idbentley 我虽然 { dataPoints: ... , unit } 是模型。它是什么。只是 dataPoints 是一个集合。所以像@Stoive回答中提到的那样对待它。采摘操作也不是那种费用。它只是将模型映射到单位。
    猜你喜欢
    • 1970-01-01
    • 2018-08-26
    • 2012-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多