KnockoutJS - 如何从计算的observable中排除observable

时间:2012-07-19 02:37:25

标签: knockout.js

我有一个计算的observable,它使用ko.toJS()从视图模型中发布值(内部可观察量)。其中一个内部可观察对象绑定到文本框。如何防止对文本框的更改自动触发计算的observable(即回发)?

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

2 个答案:

答案 0 :(得分:14)

Knockout 2.2+包含peek函数,无需订阅即可访问observable。所以你可以做到以下几点:

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

如果您坚持使用Knockout 2.1.0,您可以手动扩展observable以添加peek这样的内容(感谢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;
};

然后将backdoorObservable用于OrderNumber

OrderNumber: backdoorObservable()

答案 1 :(得分:0)

我写了这个小插件来帮助我解决许多类似情况:

https://github.com/ZiadJ/knockoutjs-reactor

要忽略某些字段,它会为您提供hide选项,您可以这样使用:

ko.watch(SearchParams, { hide: [SearchParams.OrderNumber] }, function () {
    NS.post({
        url: '/SomeUrl',
        data: ko.toJS(SearchParams)
    });
}).extend({ throttle: 1 });