How can I map self.fThings
to a flat array containing Name
using ko.util
functions?
function FItem(name) {
var self = this;
self.Name = ko.observable(name);
}
self.fThings = ko.observableArray([new FItem("Raindrops on roses"),
new FItem("Whiskers on kittens"),
new FItem("Bright copper kettles"),
new FItem("Warm woolen mittens"),
new FItem("Brown paper packages")]);
I've attempted this with both arrayForEach
and arrayMap
without success. I think because the observable
contained in the observableArray
complicates the operation. I've considered it might be bad practice to contain an observable
in an observableArray
(is it?), however changing to a static value breaks another part of the application.
It's possible to use arrayForEach
(or a for
loop for that matter) to achieve this:
self.plainThings = ko.computed(function() {
var ret = [];
ko.utils.arrayForEach(self.fThings(), function(item) {
ret.push(item.Name());
});
return ret;
});
You could do this in a normal function or just call it as needed, but the benefit of doing it inside a computed
is that if another item is added to (or one removed from) the observableArray
, or one of the Name
values change, anything that's bound to the plain array returned from the plainThings
computed would also get updated. Demo fiddle here.
Or as you say, you can also do this with arrayMap
. That could look like this:
self.plainThings = ko.computed(function() {
return ko.utils.arrayMap(self.fThings(), function(item) {
return item.Name();
});
});
Demo fiddle. Or if you don't need it in a computed, just use the inner section directly:
var plainArray = ko.utils.arrayMap(self.fThings(), function(item) {
return item.Name();
});
I wouldn't worry about putting observable
s inside observableArray
s etc - I've worked on viewmodels where things can be nested quite deeply, and thanks to knockout's chaining, when something updates, it all bubbles through nicely.