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

how to make computed re-evaluate when dynamic

本文关键字:新评估 评估 计算 动态      更新时间:2023-09-26

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

有没有办法让这些计算值重新评估,即使我正在进行动态检查?超级秘密的内部淘汰 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);
}

在 jsfiddle 中创建一个独立的样本后,我找到了修复程序,即将deferEvaluation设置为有问题的计算结果。

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/