Lau*_*ila 1 aurelia aurelia-binding
我想用Aurelia构建一个简单的自定义组件,允许用户输入一个或多个字符串.如果有多个项目,列表应显示列表中每个项目的删除按钮.
我的问题是,当列表中有多个项目时,列表的第一项不显示删除按钮. 这是它的外观
这是我对自定义列表组件的代码和html:
视图
<template>
<div repeat.for="item of items">
<input type="text" value.bind="items[$index]">
<button click.delegate="remove($index)"
if.bind="hasMoreThanOne()">Remove</button>
</div>
<button click.delegate="add()">Add</button>
</template>
Run Code Online (Sandbox Code Playgroud)
视图模型
export class List {
items: string[];
constructor() {
this.items = [];
this.add();
}
add() {
this.items.push("");
}
hasMoreThanOne() {
return this.items.length > 1;
}
remove(index) {
this.items.splice(index,1);
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是双重的:
Ash*_*ant 11
Aurelia将作为bind命令一部分的任何函数视为纯函数.这意味着在传递给函数的参数发生更改之前,它不会再次调用该函数.由于hasMoreThanOne()返回值基于不是函数参数的东西而改变(当然,因为函数没有任何参数),Aurelia不会再次调用该函数.
Aurelia在数组更改时不重新评估函数的原因是转发器已经过优化,并且发现数组中的第一项没有更改,因此它只是继续使用它拥有的现有DOM.使用正确创建的视图,这有助于大大提高性能,但在您的情况下,它会导致不必要的问题.
您通过使用getter找到了一种非最佳方法来处理此问题.这是非最佳的原因是Aurelia默认情况下每隔200ms使用脏检查来检查getter的变化.这解决了您遇到的问题,但不是理想的性能.
考虑到hasMoreThanOne()函数的简单性,最简单的选择就是简单地在绑定中内联函数,如下所示:
<template>
<div repeat.for="item of items">
<input type="text" value.bind="items[$index]">
<button click.delegate="remove($index)"
if.bind="items.length > 1">Remove</button>
</div>
<button click.delegate="add()">Add</button>
</template>
Run Code Online (Sandbox Code Playgroud)
老实说,我可能会如何处理这个问题.
你也可以像你一样使用getter,但是将computedFrom装饰器连接到它以防止脏检查:
import {computedFrom} from 'aurelia-framework';
export class List {
items: string[];
constructor() {
this.items = [];
this.add();
}
add() {
this.items.push("");
}
@computedFrom('items.length')
get hasMoreThanOne() {
return this.items.length > 1;
}
remove(index) {
this.items.splice(index,1);
}
}
Run Code Online (Sandbox Code Playgroud)
这将为您提供与我上面使用的内联绑定完全相同的性能,但还有更多的代码要编写.