Javascript 主干集合中所有模型的集合属性

Javascript 主干集合中所有模型的集合属性,javascript,backbone.js,underscore.js,backbone.js-collections,Javascript,Backbone.js,Underscore.js,Backbone.js Collections,我知道使用Pulk方法可以在主干集合中获得每个模型的属性数组 var idsInCollection = collection.pluck('id'); // outputs ["id1","id2"...] 我想知道是否有一个方法可以为集合中的每个模型设置属性 var urlArray = ["https://url1", "https://url1" ...]; collection.WHAT_IS_THIS_METHOD({"urls": urlArray}); 我不知道有什么方法,但

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

var idsInCollection = collection.pluck('id'); // outputs ["id1","id2"...]
我想知道是否有一个方法可以为集合中的每个模型设置属性

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

我不知道有什么方法,但你可以试试:

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

实际上没有预先存在的方法,但是
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
    }
});
*编辑*


主干网已经添加了自己的
set
方法,如果您覆盖它,您将完全破坏您的
集合
。因此,上面的示例应该重命名为
setmodeldattributes
,或者其他任何不是
set

的名称,如果您使用的是根据下划线调用语法,则应该使用 _.invoke(列表、方法名、*参数)

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

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

希望有帮助:)

扩展David的答案,您可以轻松地将此功能放入集合的自定义方法中。下面是我使用coffeescript的方法:

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中实现它,它是完全一样的,但是没有利用类或splat的强大功能。更像是:

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

我只是想根据MachineHost的版本发布我的稍微更新的方法。这将使用lodash invokeMap方法而不是下划线的invoke。它支持与标准model.set方法相同的可选语法。。。e、 g.('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;
    }
});

您想将整个数组设置为每个模型,还是只将一个数组项设置为每个具有相应索引的模型?每个具有相应索引的模型的数组项xoh ya,这就是我现在所做的。我只是想知道是否有更好的方法。我会说使用
每个
(下划线)而不是
forEach
(本机)
forEach
不兼容跨浏览器。@anushr David实际上在这里引用的是下划线方法,而不是本机方法。主干集合代理下划线方法:@Russ我的错误,谢谢你指出。我一直忘了下划线中的
forEach
助手。我认为你错了。因为这会给集合中的每个模型分配一个数组。哦,我误解了你的意图。在这种情况下,您绝对需要迭代。这是错误的
.invoke(collection,methodName,arguments)
转换为
collection.invoke(methodName,arguments)
–主干线或下划线从不翻转参数的顺序-->
collection.invoke('set',{url:someUrl})