2013-06-15 10 views
9

Próbuję zerwać wiele atrybutów z kolekcji kręgosłupa, ale zwraca ona undefined.Jak zerwać wiele atrybutów z kolekcji Szkielet?

kolekcja

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

... //many models 

Próbuję dostać wiele atrybutów ze zbioru.

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

Oczekiwany wyjście

[{//multiple attributes},{}] 

jest jakiś alternatywny sposób, aby dostać wiele atrybutów?

+0

Przykład jsFiddle byłby miły. – elclanrs

Odpowiedz

17

Jak @elclanrs powiedział collection.pluck wydobywa pojedynczy atrybut , będziesz musiał użyć _.map z niestandardową funkcją ekstrakcji. Coś jak

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); 

a demo http://jsfiddle.net/U7p9u/


Można by uprościć ten apel łącząc Collection.invoke i Model.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/


W podobnym duchu, jeśli funkcja ekstrakcji jest zdefiniowany na prototypie swoich modeli:

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/

3

W docs mówi:

„[oskubać jest] Odpowiednik nazywając mapę i przekazujących pojedynczy atrybut z iteracyjnej.”

To pozwala mi wierzyć, że nie jest to możliwe z wielu właściwości, ponieważ jesteś w zasadzie zastępowania jeden elementu w kolekcji z jednej jego właściwości. Więc w zasadzie to robisz:

var collect = [{a:'foo',b:'baz'},{a:'lol',b:'fur'}]; 

var key = 'a'; 
var result = collect.map(function(o){ return o[key] }); 

Możliwym rozwiązaniem byłoby zwrócić tablicę, a następnie spłaszczyć go mniej więcej tak:

result = [].concat.apply([],collect.map(function(o){ return [o.a,o.b]; })); 

console.log(result); //=> ["foo", "baz", "lol", "fur"] 
+0

spójrz na ten https://github.com/documentcloud/underscore/pull/1116 –

+0

Cóż, to dobra informacja, ale mówi: "To było omawiane kilka razy wcześniej i nie sądzę, że to dobrze pasuje. "_ Musiałbyś znaleźć alternatywne rozwiązanie. Zmieniłem moje pytanie za pomocą rozwiązania, wystarczy, że zredukujesz je do swojej małej funkcji. – elclanrs

+0

Dezorientuję !, czy można zwrócić wiele atrybutów? –

0

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

można dodać do kolekcji select metod i modeli.
(lub wymienić go co uważasz za stosowne)

/** 
    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); 
    }); 
} 

Pozwoliłoby to wybrać wiele właściwości we wszystkich modelach kolekcji, lub wybrać wiele obiektów na modelu.

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