Angular删除数组元素后如何触发变更检测更新视图?
问题原因分析
首先最核心的问题是变量名拼写不匹配:
- 组件类中定义的数组属性是小写开头的
client - 模板中绑定的是大写开头的
{{ Client }},二者完全是两个不同的变量,模板绑定的Client默认是undefined,自然不会随client的修改产生任何变化。
如果修正拼写问题后仍然出现不更新的情况,通常是因为你开启了ChangeDetectionStrategy.OnPush变更检测策略:Angular的OnPush策略默认只会在输入属性引用变化、组件内部事件触发、手动触发变更检测三种情况下更新视图,而pop()是数组的原地修改方法,不会改变数组本身的引用,所以不会触发OnPush策略下的自动更新。
可行的解决方法
1. 先修正变量名拼写
把模板中的绑定改成和组件属性一致的小写开头即可,默认变更检测策略下改完就能正常同步更新:
<pre>{{ client }}</pre>
2. OnPush策略下的额外处理
如果你的组件使用了OnPush策略,可以任选一种方式处理:
方法1:修改数组时替换引用
不使用原地修改的pop(),而是返回新数组触发引用变化,自动触发变更检测:
deleteClient() { this.client = this.client.slice(0, -1); }
方法2:手动触发变更检测
注入ChangeDetectorRef,修改数组后手动通知Angular更新视图:
import { ChangeDetectorRef, ChangeDetectionStrategy, Component } from '@angular/core'; @Component({ selector: 'app-update-view', templateUrl: './update-view.component.html', // 仅开启OnPush策略时需要加下面这行 changeDetection: ChangeDetectionStrategy.OnPush, styles: [ ] }) export class UpdateView { public client: string[] = ['client 1', 'client 2', 'client 3', 'client 4']; constructor(private cdr: ChangeDetectorRef) { } deleteClient() { this.client.pop(); this.cdr.markForCheck(); // 标记当前组件为需要更新状态,下次变更检测周期更新视图 // 也可以用 this.cdr.detectChanges() 立即触发当前组件及子组件的变更检测 } }
内容的提问来源于stack exchange,提问作者Rafael Velazco
相关产品推荐
相关产品推荐

