【问题标题】:How to pluck multiple attributes from a Backbone collection?如何从 Backbone 集合中提取多个属性?
【发布时间】:2013-06-15 07:38:13
【问题描述】:

我正在尝试从 Backbone 集合中提取多个属性,但它返回 undefined

收藏

{
    id:1,
    name:"raju",
    age:23,
    sex:male,
    hobbies:..
}
{
    id:2,
    name:"ramesh",
    age:43,
    sex:male,
    hobbies:..
}

... //many models

我正在尝试从集合中获取多个属性。

collection.pluck(["id","name","age","sex"]);

预期输出

[{//multiple attributes},{}]

有没有其他方法可以获取多个属性?

【问题讨论】:

  • 一个 jsFiddle 的例子会很好。

标签: javascript jquery html backbone.js


【解决方案1】:

正如@elclanrs 所说,collection.pluck 提取单个属性,您必须将_.map 与自定义提取功能一起使用。类似的东西

var c = new Backbone.Collection([
    {id: 1, name: "raju", age: 23, sex: "male"},
    {id: 2, name: "ramesh", age: 43, sex: "male"}
]);

var plucked = c.map(function (model) {
    return _.pick(model.toJSON(), ["name", "age"]);
});
console.log(plucked);

还有一个演示http://jsfiddle.net/U7p9u/


您可以通过组合 Collection.invokeModel.pick 来简化此调用

var c = new Backbone.Collection([
    {id: 1, name: "raju", age: 23, sex: "male"},
    {id: 2, name: "ramesh", age: 43, sex: "male"}
]);

plucked = c.invoke("pick", ["name", "age"]);  
console.log(plucked);

http://jsfiddle.net/U7p9u/5/


本着类似的精神,如果您的提取函数是在模型原型上定义的:

var M = Backbone.Model.extend({
    mypluck: function () {
        return this.pick("name", "age");
    }
});

var C = Backbone.Collection.extend({
    model: M
});

var c = new C([
    {id: 1, name: "raju", age: 23, sex: "male"},
    {id: 2, name: "ramesh", age: 43, sex: "male"}
]);

var plucked = c.invoke("mypluck");
console.log(plucked);

http://jsfiddle.net/U7p9u/3/

【讨论】:

    【解决方案2】:

    在文档中它说:

    "[pluck is the] 等价于调用map并返回一个single 来自迭代器的属性。”

    这让我相信使用多个属性是不可能的,因为您基本上是用 一个 属性替换集合中的 一个 项。所以基本上你正在这样做:

    var collect = [{a:'foo',b:'baz'},{a:'lol',b:'fur'}];
    
    var key = 'a';
    var result = collect.map(function(o){ return o[key] });
    

    一种可能的解决方案是返回一个数组,然后将其展平,如下所示:

    result = [].concat.apply([],collect.map(function(o){ return [o.a,o.b]; }));
    
    console.log(result); //=> ["foo", "baz", "lol", "fur"]
    

    【讨论】:

    • 嗯,这是很好的信息,但它说 “这实际上已经讨论过几次了,我认为它不太合适。” 所以你应该有寻找替代解决方案。我用一个解决方案编辑了我的问题,你只需要将它抽象成你自己的小函数。
    • 我很困惑!,pluck 可以返回多个属性吗?
    • 显然不是。检查相关问题,你会发现这个github.com/documentcloud/underscore/pull/1113
    【解决方案3】:

    http://jsfiddle.net/CoryDanielson/Lj3r85ew/

    您可以将select 方法添加到集合和模型中。
    (或者你觉得合适的名字)

    /**
        Backbone Model Select/Multi-get -------------------------------------------
    */
    
    Backbone.Model.prototype.select = function(props) {  
        if ( arguments.length > 1 ) {
            props = slice.call(arguments);
        }
        if ( _.isArray(arguments[0]) ) {
            props = arguments[0];
        }
    
        // If requesting multiple, return all props
        if ( _.isArray(props) ) {
            return _.object(props, _.map(props, _.bind(this.get, this)));
        }
        // Else, return single property
        return this.get(props);
    }
    
    /**
        Backbone Collection Select ------------------------------------------------
    */
    Backbone.Collection.prototype.select = function(props) {
        if ( arguments.length > 1 ) {
            props = slice.call(arguments);
        }
        if ( _.isArray(arguments[0]) ) {
            props = arguments[0];
        }
    
        return _.map(this.models, function(m) {
            return m.select(props);
        });
    }
    

    这将允许您在集合的所有模型中选择多个属性,或在模型上选择多个属性。

    collection.select('id', 'first', 'last');   // or ['id', 'first', 'last']
    model.select('first', 'last');              // or ['first', 'last']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-28
      • 1970-01-01
      • 2021-10-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多