我想使用 Aurelia 构建一个简单的自定义组件,允许用户输入一个或多个字符串。当有多个项目时,应显示列表remove列表中每个项目的按钮。
我的问题是列表的第一项没有显示remove当列表中有多个项目时按钮。这就是它的样子 https://i.stack.imgur.com/suVD6.png
这是我的自定义列表组件的代码和 html:
View
<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>
视图模型
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);
}
}
我的问题有两个:
- 为什么列表长度更改时第一个列表项不会自动更新?
- 如何使第一项也显示删除按钮?
Aurelia 对待任何属于bind
命令作为纯函数。这意味着在传递给函数的参数发生更改之前,它不会再次调用该函数。自从hasMoreThanOne()
具有一个返回值,该值根据不是函数参数的内容而变化(当然,因为该函数没有任何参数),Aurelia 不会再次调用该函数。
当数组更改时,Aurelia 不会重新评估函数的原因是中继器经过优化,并且发现数组中的第一项没有更改,因此它只是继续使用现有的 DOM。通过正确创建的视图,这有助于极大地提高性能,但就您而言,它会导致不必要的问题。
您找到了一种非最佳的方法来处理这个问题,那就是使用 getter。这不是最佳的原因是 Aurelia 默认情况下每 200 毫秒使用一次脏检查来检查 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>
老实说,这就是我可能会处理的方式。
您也可以像现在一样使用吸气剂,但附加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);
}
}
这将为您提供与我上面使用的内联绑定完全相同的性能,但需要编写更多的代码。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)