我创建了一个模型,它封装了我在很多模型上使用的过滤逻辑,但是我遇到了一个问题,isFiltering
和clearFilterImg
计算只发生一次,因为我正在动态评估每个模型在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);
}
答案 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