使用Angular中的非实例化值


<ul class="todo-list">
<li *ngFor="let todo of todos" [ngClass]="{completed: todo.isDone, editing: todo.editing}" >
<div class="view">
<input class="toggle"
type="checkbox"
[checked]="todo.isDone"
(click)="toggleTodo(todo)">
<label (dblclick)="todo.editing = true">{{todo.title}}</label>
<button class="destroy" (click)="destroyTodo(todo)"></button>
</div>
<input class="edit"
#updatedTodo
[value]="todo.title"
(blur)="updateTodo(todo, updatedTodo.value)"
(keyup.escape)="todo.editing = false"
(keyup.enter)="updateTodo(todo, updatedTodo.value)">
</li>
</ul>

https://github.com/amejiarosario/angular-todo-app/blob/master/src/app/todo/todo.component.html

我修改了这个存储库中的代码,我注意到的一件事是,在原始todos数组对象中找不到编辑属性,它是在html组件中创建的,或者可能在其他地方创建的,我认为它是在事件侦听器中实例化的,但这样做是个好主意吗?我遇到了问题,所以我不得不在todo中实例化它。

此外,在事件侦听器中实例化它意味着我们不能修改服务组件内部的属性编辑,对吧?

它是在事件侦听器中设置的。此处:

<label (dblclick)="todo.editing = true">

这里:

(keyup.escape)="todo.editing = false"

当然,如果它没有在其他地方初始化,那么它将在这里初始化。但不管怎样,从Angular的角度来看,以这种方式变异对象是一个可怕的想法。例如,它不适用于OnPush更改检测策略。不变性原则对Angular来说很重要,因为如果你正确地管理更改检测,它只会通过引用进行检查,变异的更改不一定会出现。这些事件真正应该做的是触发函数,通过重建特定对象来更新它,然后通过重建数组来替换数组中的对象。例如

setIsEditing(todoToUpdate: Todo, editing: boolean): void {
this.todos = this.todos.map(todo => todo === todoToUpdate ? {...todoToUpdate, editing} : todo);
}

当然,通过这种方式,对todo的更改将通过*ngFor销毁并重新创建todoDOM元素(这是有意的(。但是您也可以通过使用trackBy函数来改进这一点。类似于component.ts

trackById(index, todo: Todo): string {
return todo.id;
}

component.html

<li *ngFor="let todo of todos; trackBy: trackById" [class.completed]="todo.isDone" [class.editing]="todo.editing" >

你不必总是这样做,但我只是想给你举个例子。你这样做的原因是为了在现实世界中的应用程序中获得出色的性能。但你的应用程序看起来更像是一个学习应用程序,因此以最简单的方式做事,我认为这也是为什么在事件处理程序中添加属性的原因。

HTML属性只由文本组成,而不是括号((/((、括号([/](或curlies({/}(。我认为这就是为什么你的代码不能工作,这不是一个角度的问题。

最新更新