我有一些ko.pureComputed
属性,通常会在自身内部存储大量数据。
当这些ko.pureComputed
属性进入 sleep 状态(没有人订阅它们)时,我不再需要这些数据,直到他们回到 listen 状态(有人订阅了他们)。
在这段时间内,当他们处于 sleep 状态时,我希望ko.pureComputed
属性清除它们的值,以便垃圾收集器可以从内存中删除该计算数据,然后,当我再次需要计算数据时,也就是说,当ko.pureComputed
返回到监听状态时,我想重新计算计算数据。
这可能吗?
有关我的用例场景的更多详细信息:
我的网站是单页应用程序,意味着Javascript框架( Durandal )为用户显示切换页面(HTML和JS)。
某些页面需要存储大量数据的计算属性。我希望将ko.pureComputed
用于此目的,因为一旦用户离开其页面,即一旦ko.pureComputed
进入 sleep 状态,它就会停止更新因为它没有更多的听众。
( Durandal 在用户离开或访问页面时,将页面的JS视图模型从HTML视图中重新分配并重新附加到HTML视图中
问题是ko.pureComputed
保持其最新值被缓存。
在我的例子中,这些值是大型对象的大型数组,占用了大量的内存。我不想再处理这些数据了。
有没有办法在{{1>}进入 sleep 状态(当用户离开页面时)时清除缓存的值,然后在ko.pureComputed
时重新初始化{ {1}}返回监听状态(当用户重新访问该页面时)?
答案 0 :(得分:2)
使用纯计算的状态更改事件,我们可以告诉计算机在其休眠时清除其值。这是一个包装函数,可以全部设置:
function computedValueOnlyWhenActive(readFunction) {
var isAwake = ko.observable(false),
theComputed = ko.pureComputed(function () {
if (isAwake()) {
return readFunction();
}
});
theComputed.subscribe(function() {
isAwake(true);
}, undefined, "awake");
theComputed.subscribe(function() {
isAwake(false);
theComputed.peek(); // force reevaluation
}, undefined, "asleep");
return theComputed;
}
答案 1 :(得分:1)
这不是您提出的具体问题的答案,但根据您的具体情况,这可能是一个更有帮助的答案。
在Durandal中,路由器插件通过使用requireJS调用异步加载指定的模块进行导航。一旦它检索到模块,它就会检查结果是对象还是函数,如果它是一个函数,它将从函数中实例化一个新对象。如果它是一个对象,它只使用该对象。
RequireJS会自动缓存它检索到的模块,因为如果模块已经下载了模块,它就不会从服务器重新获取模块。因此,如果您的模块定义是普通对象,那么每次都会显示相同的对象。
此模块定义将在导航之间保存其状态:
define(['durandal/app'], function (app) {
var title = 'myView';
var vm = {
title: title;
};
return vm;
});
此模块定义将创建一个新对象,并将重新绑定所有敲除绑定,从而在每个导航中生成一个新加载的屏幕。
define(['durandal/app'], function (app) {
var title = 'myView';
var vm = function(){
this.title = title;
};
return vm;
});
修改强> 对于更细粒度的durandal解决方案,也适用于较旧版本的淘汰赛(即在pureComputed之前),您可以将这个概念与迈克尔最佳结合使用isAwake observable和durandal的视图激活和停用生命周期钩子。
function viewModel(){
var self = this;
this.isAwake = ko.observable(true);
this.theComputed = ko.computed(function () {
if (isAwake()) {
return myValue();
}
return "";
});
this.activate = function(){
self.isAwake(true);
}
this.deactivate = function(){
self.isAwake(false);
}
}
var vm = new viewModel();
return vm; //return the instance not the function
http://durandaljs.com/documentation/Hooking-Lifecycle-Callbacks.html