考虑到下面的 Angular Signals 示例,我有点困惑何时应该使用 Signal API,例如 mutate() 和 update(),而 Array API(例如 forEach)就足够了触发反应并更新 UI/模板?这里有什么区别呢?使用的 Angular 版本:16.0.1
@Component({
selector: 'my-app',
standalone: true,
imports: [CommonModule],
template: `
{{usersList() | json}}
`,
})
export class App {
usersList: Signal<any> = inject(UserService).getUsersList();
constructor() {
}
}
bootstrapApplication(App);
@Injectable({
providedIn: 'root',
})
export class UserService {
private users = signal([
{ id: 1, name: 'Peter', country: 'USA' },
{ id: 2, name: 'Party Boy', country: 'USA' },
{ id: 3, name: 'John Connor', country: 'USA' },
]);
constructor() {
window.setTimeout(()=>{
this.changeUsersListWithoutMutate();
}, 3000),
window.setTimeout(()=>{
this.changeUsersListWithMutate();
}, 5000)
}
changeUsersListWithoutMutate(){
this.users().forEach((item) => {
if (item.id === 1) {
item.name = "changeListWithoutMutate";
}
});
}
changeUsersListWithMutate(){
this.users.mutate((data) => {
data.forEach((item) => {
if (item.id === 1) {
item.name = "changeListWithMutate";
}
});
});
}
getUsersList() {
return this.users;
}
}
您在示例中观察到的是标准变更检测,因为您依赖于
setTimeout()
。
setTimeout
是 zone.js
修补的 API 之一,这意味着每次调用 Angular 都会触发更改检测周期并刷新 DOM。
话虽这么说,回到信号基础知识:
在
changeUsersListWithoutMutate
中,您没有更新信号,因为您正在读取其值并更改其嵌套值。信号本身没有办法知道它已经更新了。
这就是为什么
changeUsersListWithMutate
是要走的路。您明确告诉信号您正在更新其值,并且信号将触发更改检测。
如果我的回答有不清楚的地方,请告诉我。