我有一个在Aurelia CLI上运行的web应用程序,并使用knockout进行绑定(因为之前我转换为Aurelia的应用程序广泛使用了淘汰赛)。为此,我使用Aurelia-knockout插件没有问题。
我做了(作为测试)两个简单的视图(和相应的路线):
#/test1
#/test2
以下是观点:
<!-- test1.html -->
<template view-cache="*">
<div knockout>
<br /><br />
<div data-bind="foreach: values1">
<div data-bind="text: $data"></div>
</div>
</div>
</template>
<!-- test2.html -->
<template view-cache="*">
<div knockout>
<br /><br />
<div data-bind="foreach: values2">
<div data-bind="text: $data"></div>
</div>
</div>
</template>
正如您从html中看到的那样,我正在缓存视图using the "view-cache" attribute,以便在我导航回该视图时不会重新加载它们。 相应的模型简单定义如下:
//test1.js
export class Test1 {
values1 = ko.observableArray([1,2,3]);
}
//test2.js
export class Test2 {
values2 = ko.observableArray([4,5,6]);
}
这是我的路由器配置:
routes = [
{ route: ['', 'test1'], moduleId: 'views/test1', name: 'test1' },
{ route: ['test2'], moduleId: 'views/test2', name: 'test2' }
];
config.map(routes);
首次加载页面时,我正确地看到了
123
当我导航到#/ test2时,我正确地看到了
456
但如果我导航回#test1,我会看到
112233
如果我现在再次访问#test2,我会看到数字'重复'。每次我来回走动,都会添加数字。例如,如果我访问#test1 4次,我会得到
111122223333
注意:如果我不缓存视图(通过省略&#34; view-cache&#34;属性),一切正常。
但我想使用视图缓存。据我所知,这是Aurelia团队仍在努力的一个功能,我想知道是否有人有同样的问题以及如何解决它。每当导航发生时,看起来好像敲除了已经存在的敲除绑定。
更新
我刚尝试使用这样的singleton decorator:
import * as Framework from 'aurelia-framework';
@Framework.singleton()
export class Test1 {
activated = false;
values1 = ko.observableArray([1,2,3]);
constructor(){
console.log('constructed')
}
activate() {
if (this.activated) {
console.log('activated')
var val = this.values1();
this.values1([]);
this.values1([1,2,3]);
console.log(this.values1())
} else this.activated = true;
}
}
改变之处在于不再调用构造函数,并且viewModel的状态是持久的(这意味着,第二次导航到#test1,变量&#34;激活&#34;是真的。< / p>
仍然,敲除绑定的输出与以前相同。
答案 0 :(得分:0)
我认为你的激活方法可能存在逻辑问题。 我相信应该阅读
if (!this.activated) ....
并移动
this.activated = true
如果像这样的内容
activate() {
if (!this.activated) {
console.log('activated')
var val = this.values1();
this.values1([]);
this.values1([1,2,3]);
console.log(this.values1());
this.activated = true;
}
}
答案 1 :(得分:0)
好的,我找到了一种绕过这个问题的方法,使用KnockoutBindable as explained here:
//test1.html (and test2.html, same code only with variable name values1 instead of values2)
<template view-cache="*">
<div knockout>
<div repeat.for="item of values2">
${item}
</div>
</div>
</template>
//test1.js (and test2.js, same as above)
import * as Framework from 'aurelia-framework';
import {KnockoutBindable} from "aurelia-knockout";
import {inject} from 'aurelia-dependency-injection';
@Framework.singleton()
@inject(KnockoutBindable)
export class Test2 {
activationData = {
values2: ko.observableArray([4,5,6])
}
knockoutBindable;
@Framework.bindable
values2;
constructor(kb) {
this.knockoutBindable = kb;
}
activate() {
this.knockoutBindable.applyBindableValues(this.activationData, this);
}
}
现在,如果我来回走动,那么正确保留了数值。 这样做的缺点是我必须创建一个额外的变量来“镜像”敲除变量,而html中的变量使用aurelia语法来避免这个问题。
答案 2 :(得分:0)
采取from here:
Aurelia缓存整个&#34; View&#34;如果切换到另一个视图,则对象(包括保存html的文档片段)。如果你回去,Aurelia使用缓存的视图并将其绑定到新的视图模型。这样可以正常工作,因为所有Aurelia绑定都会被完全处理。但模板引擎并不知道动态生成html的Knockout语法。它将它视为&#34;普通的html&#34;并且不会恢复之前运行的更改。
如果从Aurelia调用unbind回调,则此插件调用ko.cleanNode(...)。这将恢复Knockout之前所做的更改(这正是您所需要的)。不幸的是,回调被称为太迟了。旧视图已经分离,这种清理不起作用。文档片段按原样缓存。