Reputation: 1184
I have a problem with knockoutJS i can't figure out
I have two observableArrays; One containing all available items and one containing all selected items.
How can i return a new array, that contains all the available items ( with all the selected items removed from it)?
Upvotes: 5
Views: 1082
Reputation: 2910
I'd use .filter
or ko.utils.arrayFilter
, and .indexOf
or equivalent:
this.remainingOptions = ko.computed(function(){
return this.availableOptions().filter(function(option) {
return this.selectedOptions().indexOf( option ) === -1;
}.bind(this));
},this);
Fiddle: http://jsfiddle.net/p3RMD/1/
Edit: Also see the Knockout Projections plugin if you want more efficient .map
and .filter
methods on observableArrays
Upvotes: 3
Reputation: 1184
EDIT:
Since my specific problem, was observableArrays containing objects ( which i failed to state in my question ). The answers provided did not fix my problem, although, it did answer the question nicely, which is why i am not changing answer.
for anyone interested in how i solved the problem, here is the code:
var self = this;
self.users = ko.observableArray([]);
self.roles = ko.observableArray([]);
self.selectedUser = ko.observable();
self.remainingOptions = ko.computed(function () {
return (self.roles()).filter(function (option) {
var current = option.Name();
var keep = true;
if (self.selectedUser() !== undefined) {
ko.utils.arrayFirst(self.selectedUser().Roles(), function (item) {
if (keep) {
keep = (current !== item.Name());
}
return (current === item.Name());
});
}
return keep;
}); //end filter
}); //end remaininOptions
the Role object is just an object with a Name property.
Upvotes: 1
Reputation: 960
If you want to return a new array, without modifying the original array, your best bet is to use a computed observable.
var ViewModel = function(){
this.available = ko.observableArray([1,2,3,4,5]);
this.selected = ko.observableArray([1,3,5]);
this.remaining = ko.computed(function(){
var remaining = ko.observableArray();
remaining(ko.toJS(this.availableOptions))
remaining.removeAll(this.selectedOptions());
return remaining();
}, this);
}
Here's a link to a working example:
http://jsfiddle.net/nathanjones/p3RMD/
Edit: fixed sample code.
Upvotes: 1
Reputation: 4735
The standard removeAll method should handle this. From documentation:
myObservableArray.removeAll(['Chad', 132, undefined]) removes all values that equal 'Chad', 123, or undefined and returns them as an array
Do you need to extract the available items without altering the original, all available items array?
Upvotes: 2