在我的一个视图模型中,我有一个函数Control
,它稍后创建一个对象以绑定到视图:
(代码只是复制我的viewmodel,因此它可能不完整或包含一些错误。如果你需要更多细节,请在下面的评论中询问。因为这个例子引用了durandaljs框架,我不能提供一个JsFiddle。)
function Control ( value ) {
var self = this;
self.param = value;
self.param1 = ko.observable(value.text());
self.param2 = ko.computed(function() {
read: function(){
return getString(self.param.text()).StringValue();
},
write: function(newValue){
stringsArray.push(
{StringID: ko.observable(-1), StringValue: ko.observable(newValue)});
self.param.text(-1);
},
owner: self
});
self.param3 = ko.computed(function() {
return self.param2() + ' something_else';
});
self.param1.subscribe(function( newValue ) {
if ( newValue ) {
self.param3(newValue + 'text');
}
});
}
var controls = ko.observableArray([
new Control({id: 1, text: ko.observable(2)}),
new Control({id: 2, text: ko.observable(4)}),
new Control({id: 2, text: ko.observable(1)})
]);
var stringsArray = ko.observableArray([
{StringID: ko.observable(1), StringValue: ko.observable('aaa')},
{StringID: ko.observable(2), StringValue: ko.observable('bbb')}
{StringID: ko.observable(3), StringValue: ko.observable('ccc')}
{StringID: ko.observable(4), StringValue: ko.observable('ddd')}
{StringID: ko.observable(5), StringValue: ko.observable('eee')}
{StringID: ko.observable(6), StringValue: ko.observable('fff')}
]); // data retrieved from the database
var deactivate = function() {
controls.removeAll();
stringsArray.removeAll();
};
var vm = {
deactivate: deactivate,
controls: controls,
stringsArray: stringsArray
};
return vm;
function getString ( stringID ) {
for ( var i = 0; i < stringsArray().length; i++ ) {
if ( stringsArray()[i].StringID() === stringID ) {
return stringsArray()[i];
}
}
return undefined;
}
我的问题是从函数创建的对象是全局范围的,因此当我取消激活viewmodel时,它们仍然存在于内存中。
我应该如何重写function Control(value)
,以便它创建的对象具有viewmodel范围。它们仅在viewmodel处于活动状态时存在,并在我从deactivate
方法中的observableArray中删除它们时被丢弃?
答案 0 :(得分:0)
有趣的例子,但我不确定上面的代码是否真正反映了你正在做的事情,或者它是否是一个复制/粘贴问题。
我在http://dfiddle.github.io/dFiddle-2.0/#extras/scope提出了一个dFiddle来调试它。随意分叉和修改。
目前,当您离开视图时,Durandal的实时周期事件deactivate
会被触发removeAll
来自stringArray
和controls
的条目,但当然会留下淘汰赛observableArrays在内存中至少如果视图模型返回单例并且cacheViews设置为true。
我很可能将vm转换为构造函数,并在其上将控件移动到它自己的模块中,但当然不知道确切的要求只是一种直觉。
以下内容可以帮助您入门:
define(['durandal/system', 'jquery', 'knockout', './control'], function( system, $, ko, Control ) {
"use strict";
var vm = function() {
this.controls = ko.observableArray([
new Control('value1'),
new Control('value2'),
new Control('value2')
]);
};
vm.prototype.deactivate = function() {
this.controls.removeAll();
};
return vm;
});
define(['knockout'], function( ko ) {
"use strict";
function Control ( value ) {
this.param = value;
this.param1 = ko.observable(value.text);
this.param2 = ko.computed(function() {
//translate self.param.StringID with data from another
//an observableArray containing data retrieved from the server
//return getString(this.param.StringID()).StringValue();
return 'Computed' + this.param.id;
// ko.computed takes a context parameter
}, this);
this.param3 = ko.computed(function() {
return this.param2() + 'something_else';
}, this);
this.param1.subscribe(function( newValue ) {
if ( newValue ) {
this.param3(newValue + 'text');
}
});
}
var stringsArray = ko.observableArray([]); // data retrieved from the database
return Control;
function getString ( stringID ) {
for ( var i = 0; i < stringsArray().length; i++ ) {
if ( stringsArray()[i].StringID === stringID ) {
return stringsArray()[i];
}
}
return undefined;
}
});
提供实时版本
答案 1 :(得分:0)
显然我的问题是对象包含的ko.computed
。当我停用viewmodel时,计算机没有被删除,因为它们所依赖的一些外部数据仍在内存中。
我在这篇文章中找到了它:https://groups.google.com/d/msg/knockoutjs/4HV_PgcBNXA/ozoyXlygJHwJ
在取消激活功能中手动处理ko.computed
后,问题就消失了。