admin管理员组文章数量:1355532
I have an observable array of objects and I want to pluck out the values using underscore.js
For example:
ko.observableArray([{
id: ko.observable(1),
name: ko.observable("name1")
},
{
id: ko.observable(2),
name: ko.observable("name2")
},
...])
And I just want to pluck the values inside of the object rather than the whole observable.
Can I do this with just one mand?
I tried:
_.pluck(myArray(), "id()")
and _.pluck(myArray(), "id"())
But these return an array of undefineds and "id is not a function" respectively.
Thanks!
I have an observable array of objects and I want to pluck out the values using underscore.js
For example:
ko.observableArray([{
id: ko.observable(1),
name: ko.observable("name1")
},
{
id: ko.observable(2),
name: ko.observable("name2")
},
...])
And I just want to pluck the values inside of the object rather than the whole observable.
Can I do this with just one mand?
I tried:
_.pluck(myArray(), "id()")
and _.pluck(myArray(), "id"())
But these return an array of undefineds and "id is not a function" respectively.
Thanks!
Share Improve this question asked May 5, 2015 at 16:43 Lon KastensonLon Kastenson 3152 silver badges10 bronze badges4 Answers
Reset to default 4Short answer
Use _.invoke
instead of _.pluck
See this sample fiddle.
Long answer
_.pluck(list, propertyName)
works as documented:
A convenient version of what is perhaps the most mon use-case for map: extracting a list of property values.
Or, as better exlained on lodash docs: _.pluck(collection, path)
Gets the property value of path from all elements in collection.
So, if you do this:
_.pluck(myArray(), "id")
what you get is an array with all the id
's. And all of these id
's are observables, as in the objects of the original array
But you can use _.invoke(list, methodName, *arguments)
, which, as documented:
Calls the method named by methodName on each value in the list. Any extra arguments passed to invoke will be forwarded on to the method invocation.
or, on lodash version _.invoke(collection, path, [args])
Invokes the method at path on each element in collection, returning an array of the results of each invoked method. Any additional arguments are provided to each invoked method. If methodName is a function it is invoked for, and this bound to, each element in collection.
In this way, you execute each observable, and get its value as expected:
_.invoke(myArray(), "id")
Mind the viewmodels full of observables!
The first ment to this question has made me include this notice:
The best solution is using ko.toJS
to convert all the observables in a view model into a regular JavaScript object, with regular properties. Once you do it, underscore, or any other library, will work as expected.
The _.invoke
solution only works for a single level of observables, as this case. If there were several level of nested observables, it will pletely fail, because it invokes a function at the end of the path, not at each step of the path, for example, _.invoke
wouldn't work for this case:
var advices = [{
person: ko.observable({
name = ko.observable('John')
}),
advice: ko.observable('Beware of the observables!')
}];
In this case, you could only use _.invoke
on the first level, like this:
var sentences = _.invoke(advices,'advice');
But this wouldn't work:
var names = _.invoke(advices,'person.name');
In this call, only name
would be invoked, but person
not, so this would fail, because person
is an observable, thus it doesn't have a name
property.
NOTE: lodash is another library similar, and mostly patible with underscore, but better in some aspects
I was able to solve this by using the "map" function:
_.map(myArray(), function(item) {return item.id()});
But I was hoping to use pluck since it's the exact use-case for this type of scenario.
Because name
is a function, how about pluck
your original array into an array of functions, then using ko.toJS
to convert it into string array?
var myArray = ko.observableArray([{
id: ko.observable(1),
name: ko.observable("name1")
},
{
id: ko.observable(2),
name: ko.observable("name2")
}]);
var names = _.pluck(myArray(), 'name');
console.log(ko.toJS(names)); // Output: ["name1", "name2"]
Unwrap it first
_.pluck(ko.toJS(myArray), 'id')
_(ko.toJS(myArray)).pluck('id)
本文标签: javascriptUse underscorejs quotpluckquot on a knockout observable arrayStack Overflow
版权声明:本文标题:javascript - Use underscore.js "pluck" on a knockout observable array - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1743979387a2571015.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论