Reputation:
I have a computed observable that uses ko.toJS() to post values (inner observables) from the view model. One of the inner observables is bound to a textbox. How can I prevent changes to the textbox from automatically triggering the computed observable (i.e. the postback)?
function viewModel() {
var self = this;
self.SearchParams = {
OrderStatusID: ko.observable(),
OrderNumber: ko.observable(), // I don't want this observable to trigger the postback
OrderBy: ko.observable(),
OrderByDirection: ko.observable(),
PageIndex: ko.observable(),
PageSize: ko.observable()
};
// This computed observable automatically subscribes to every
// observable in self.SearchParams. How can I ignore changes to
// self.SearchParams.OrderNumber?
ko.computed(function () {
NS.post({
url: '/SomeUrl',
data: ko.toJS(self.SearchParams)
});
}).extend({ throttle: 1 });
}
Upvotes: 5
Views: 5010
Reputation: 1036
I wrote this little plugin to help me out in many similar situations:
https://github.com/ZiadJ/knockoutjs-reactor
To ignore certain fields it provides you with the hide
option which you can use like so:
ko.watch(SearchParams, { hide: [SearchParams.OrderNumber] }, function () {
NS.post({
url: '/SomeUrl',
data: ko.toJS(SearchParams)
});
}).extend({ throttle: 1 });
Upvotes: 0
Reputation: 16688
Knockout 2.2+ includes a peek
function to access observables without subscribing. So you could do the following:
ko.computed(function () {
var s = self.SearchParams;
NS.post({
url: '/SomeUrl',
data: {
OrderStatusID: s.OrderStatusID(),
OrderNumber: s.OrderNumber.peek(),
OrderBy: s.OrderBy(),
OrderByDirection: s.OrderByDirection(),
PageIndex: s.PageIndex(),
PageSize: s.PageSize()
}
});
}).extend({ throttle: 1 });
If you're stuck on Knockout 2.1.0, you can extend observables manually to add peek
like this (thanks Ryan Niemeyer):
var backdoorObservable = function(initialValue) {
var _value = initialValue,
result = ko.observable(initialValue);
result.peek = function() { return _value; };
result.subscribe(function(newValue) {
_value = newValue;
});
return result;
};
And then use backdoorObservable
for OrderNumber
:
OrderNumber: backdoorObservable()
Upvotes: 15