如何在动态时进行计算机重新评估

时间:2015-03-11 10:17:58

标签: javascript knockout.js

我创建了一个模型,它封装了我在很多模型上使用的过滤逻辑,但是我遇到了一个问题,isFilteringclearFilterImg计算只发生一次,因为我正在动态评估每个模型在isFiltering计算中的模型上可观察到。

即使我正在进行动态检查,有没有办法让这些计算重新评估?超级秘密内部Knockout API调用或以不同的方式重写计算可能..?

var filterModel = (function () {

    function filterModel(parent) {
        var self = this;

        // needed for the "this" argument when calling the callback
        self.parent = parent;
        // this allows us to clear the filters and only kick off one ajax call regardless of how many filters are cleared at one time
        self.filterThrottle = ko.observable().extend({ throttle: 50 });

        // not firing more than once because the observable properties are checked dynamically
        self.isFiltering = ko.computed(function () {
            console.log("isFiltering called");
            var isFiltering = false;

            for (var property in self) {
                if (self.hasOwnProperty(property) && ko.isObservable(self[property]) && !ko.isComputed(self[property])) {
                    if (self[property]()) { // dynamic property check
                        isFiltering = true;
                        break;
                    }
                }
            }
            return isFiltering;
        });

        // not firing more than once 
        self.clearFilterImg = ko.computed(function () {
            console.log("clearFilterImg called");
            if (self.isFiltering())
                return "/content/images/clear-filter.png";
            else
                return "/content/images/clear-filter-disabled.png";
        });
    }

    filterModel.prototype.clearFilters = function () {
        var self = this;
        for (var property in self) {
            if (self.hasOwnProperty(property) && ko.isObservable(self[property]) && !ko.isComputed(self[property])) {
                // only reset a property if it has a value
                if (self[property]()) {
                    self.filterThrottle(externalbyte.createUUID());
                    self[property](null);
                }
            }
        }
    };

    filterModel.prototype.subscribeToFilters = function (callback) {
        var self = this;
        // fires the callback that makes the ajax call
        self.filterThrottle.subscribe(function (newValue) {
            callback.call(self.parent, true);
        });

        // subscribe to all observables
        for (var property in self) {
            if (self.hasOwnProperty(property) && ko.isObservable(self[property]) && !ko.isComputed(self[property])) {
                self[property].subscribe(function (newValue) {
                    // update the throttling observable to a new random UUID when a filter changes
                    self.filterThrottle(createUUID());
                });
            }
        }
    };

    filterModel.prototype.createFilterObject = function (filter) {
        var self = this;
        for (var property in self) {
            if (self.hasOwnProperty(property) && ko.isObservable(self[property]) && !ko.isComputed(self[property])) {
                filter[property] = self[property]();
            }
        }
        return filter;
    };

    return filterModel;
})();

用法:

function errorLogListModel() {
    var self = this;
    // create a new filter model
    self.filters = new filterModel(self);
    // add whatever filters I want
    self.filters.errorLogId = ko.observable();
    self.filters.userId = ko.observable();
    self.filters.userName = ko.observable();
    self.getErrors = function(resetPage)
    {
        // make an ajax call to filter records
    };
    // subscribe to any filter changes and call getErrors method
    self.filters.subscribeToFilters(self.getErrors);
}

1 个答案:

答案 0 :(得分:0)

在jsfiddle中创建一个孤立的样本后,我找到了将deferEvaluation设置为true的修复程序。

self.isFiltering = ko.computed(function () {
    var isFiltering = false;

    for (var property in self) {
        if (self.hasOwnProperty(property) && ko.isObservable(self[property]) && !ko.isComputed(self[property])) {
            if (self[property]()) {
                isFiltering = true;
                break;
            }
        }
    }
    return isFiltering;
}, self, { deferEvaluation: true }); // defer evaluation until the model is fully realized

http://jsfiddle.net/StrandedPirate/rrkh66ha/27/