我刚刚开始学习 Angular 并开始使用本教程https://www.youtube.com/watch?v=JWhRMyyF7nc(我在第 2_ 节的末尾。我尝试遵循从 Angular 17 开始的所有内容并将其更改为 Angular 17。但我遇到了一个错误。基本上,我有一个愿望清单,您可以在其中添加显示为复选框的愿望,然后选中它们以将其标记为已实现,并且您可以选择是否只想显示已实现的、未实现的或未实现的。所有的愿望都由单个组件组成。这是它的 html:
<div class = "containter">
<form class = "form">
<div>
<label class="infoText">Add your wish! </label>
<input type="text" class="wishInput" [(ngModel)] = "wishToBeAdded" name ="wishAdder">
</div>
<button type="submit" class="submitButton" (click) = "$event.preventDefault(); addWish()">Submit</button>
</form>
<div class="selector">
<select class = "wishSelector" [(ngModel)] = "filterOption">
<option value = "0">All</option>
<option value = "1">Fulfilled</option>
<option value = "2">Unfulfilled</option>
</select>
</div>
<ul class ="wishList">
<label style="font-weight: 800; font-size: large;">Wishlist:</label>
<li>
@for (item of visibleItems; track $index) {
<label>
{{$index + 1}}. {{item.wishName}} {{visibleItems[$index].isComplete}}
<input type="checkbox" class = "checkbox" [checked] = "item.isComplete" (click) = "checkboxToggle(item, $event)">
</label>
<div>
</div>
} @empty {
<label> There are no wishes in wishlist </label>
}
</li>
</ul>
</div>
这是打字稿代码:
import { Component, viewChild } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { WishItem } from '../shared/modules/wishItem';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet, FormsModule],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
items: WishItem[] = [];
title = 'My FirstProject';
wishToBeAdded : string = '';
filterOption : string = '0'
get visibleItems() : WishItem[] {
switch(this.filterOption) {
case "0":
return this.items;
case "1":
return this.items.filter(value => value.isComplete);
case "2":
return this.items.filter(value => !value.isComplete);
}
return []
}
checkboxToggle(item: WishItem, element: any)
{
item.isComplete = !item.isComplete;
this.items.forEach(element => {
console.log(element.isComplete)
});
console.log(this.visibleItems);
}
addWish()
{
if(this.wishToBeAdded.length>0)
this.items.push(new WishItem(this.wishToBeAdded));
this.wishToBeAdded = '';
}
}
但是,当选择列表仅显示已完成或未完成的元素并且有人选中或取消选中其中一个元素时,会出现奇怪的情况。该元素停止显示,因为它的 isComplete 已更改,但列表中的下一个元素在检查后立即发生。相应的 WishItem 的 isComplete 属性的值仍然正确,因为我开始打印它以查看是否有问题,但事实并非如此。我不知道我是否做错了什么,或者是有关 Angular 17 的问题,因为该教程是关于某些早期版本的,或者我不明白 html 的某些内容。
(https://i.sstatic.net/A2sfSsb8.png)
在筛选元素时从列表中选中或取消选中元素后,不应对其他元素进行任何更改。
visibleItems()
返回数组的浅表副本(应用过滤器时) - 请参阅 Array.prototype.filter()checkboxToggle
传递对浅复制数组项的引用并对其进行变异从根本上来说,问题在于没有可供参考的“主”项目列表。当您对浅复制数组项执行突变时,您所做的就是这样 - 您的更改不会反映在
items
中。
您可以通过调整
checkboxToggle()
函数来解决该问题:
// Item doesn't need to be passed in here, could benefit from just passing the index and avoiding the need to use .findIndex()
checkboxToggle(item: WishItem, element: any) {
// Find the master copy of the item
const itemIndex = items.findIndex(i => /* some predicate to identify the item */);
if (itemIndex === -1) return;
// Mutate the master copy of item
this.items[itemIndex] = {
...this.items[itemIndex],
isComplete: /* isComplete logic here */
};
}
您的
visibleItems()
函数应该反映更改,因为它在每次重新渲染时执行。