【问题标题】:set attribute of all models in backbone collection设置骨干集合中所有模型的属性
【发布时间】:2012-12-02 22:49:22
【问题描述】:

我知道使用 pluck 方法我们可以在主干集合中获取每个模型的属性数组

var idsInCollection = collection.pluck('id'); // outputs ["id1","id2"...]

我想如果有一个方法可以为集合中的每个模型设置一个属性,

var urlArray = ["https://url1", "https://url1" ...];
collection.WHAT_IS_THIS_METHOD({"urls": urlArray});

【问题讨论】:

  • 您想为每个模型设置整个数组,还是只为每个模型设置一个数组条目并具有相应的索引?
  • 具有相应索引的每个模型的数组条目

标签: javascript backbone.js underscore.js backbone.js-collections


【解决方案1】:

我没有办法,但是你可以试试:

collection.forEach(function(model, index) {
    model.set(url, urlArray[index]);
});

【讨论】:

  • 哦,是的,我现在就是这样做的。我只是想知道是否有更好的方法。
  • 我会说使用each(下划线)而不是forEach(本机)。 forEach 不兼容跨浏览器。
  • @anushr David 实际上在这里引用了 Underscore 方法,而不是本机方法。 Backbone Collections 代理下划线方法:backbonejs.org/#Collection-Underscore-Methods
  • @Russ 我的错误,感谢您指出。我总是忘记下划线中的 forEach 助手。
【解决方案2】:

不完全是预先存在的方法,但invoke 让您在一行中执行类似的操作:

collection.invoke('set', {"urls": urlArray});

如果您想在所有集合上创建可重复使用的 set 方法,您可以执行以下操作:

var YourCollection = Backbone.Collection.extend({
    set: function(attributes) {
        this.invoke('set', attributes);
        // NOTE: This would need to get a little more complex to support the
        //       set(key, value) syntax
    }
});

* 编辑 *

Backbone 已经添加了自己的set 方法,如果你覆盖它,你将完全破坏你的Collection。因此上面的例子真的应该重命名为setModelAttributes,或者任何不是set的东西。

【讨论】:

  • 我认为你在这里错了。因为这会为集合中的每个模型分配一个数组。
  • 哦,我误解了你想要做什么。在这种情况下,您绝对需要迭代。
【解决方案3】:

如果您使用调用根据下划线站点的语法应该是 _.invoke(list, methodName, *arguments) http://underscorejs.org/#invoke

所以上面machineghost提到的函数应该是

collection.invoke({'url': someURL},'set');

希望有帮助:)

【讨论】:

  • 这是错误的。 _.invoke(collection, methodName, arguments) 转换为 collection.invoke(methodName, arguments) – Backbone 或 Underscore 永远不会翻转参数的顺序 --> collection.invoke('set', { url: someUrl })
【解决方案4】:

扩展大卫的答案,您可以轻松地将此功能放入集合的自定义方法中。这是我使用咖啡脚本的方法:

class Collection extends Backbone.Collection
  setAll: () ->
    _args = arguments
    @models.forEach (model) -> model.set _args...

class SomeCollection extends Collection
  url: '/some-endpoint.json'

myLovelyCollection = new SomeCollection()
myLovelyCollection.fetch
  success: (collection, response) ->
    collection.setAll someVar: true
    collection.setAll anotherVar, 'test'

如果你想在 vanilla JS 中做这件事,它是完全一样的,但没有利用类或 splats 的力量。所以更像:

var Collection = Backbone.Collection.extend({
  setAll: function () {
    var _args = arguments;
    this.models.forEach(function (model) {
      model.set.apply(model, _args);
    });
  }
});

【讨论】:

    【解决方案5】:

    只是想我会根据 machineghost 的版本发布我稍微更新的方法。这使用 lodash invokeMap 方法而不是下划线的调用。它支持与标准 model.set 方法相同的可选语法......例如('prop', 'val') 或 ({prop: 'val', prop: 'val'}) 以及接受和传递选项对象。

    var YourCollection = Backbone.Collection.extend({
        setModels: function(key, val, options) {
            var attrs;
    
            if (typeof key === 'object') {
                attrs = key;
                options = val;
            } else {
                (attrs = {})[key] = val;
            }
    
            if (attrs) {
                _.invokeMap(this, 'set', attrs, options);
            }
    
            return this;
        }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-19
      • 1970-01-01
      • 2012-07-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多