gpt4 book ai didi

angular - HTML 模板不会更新,除非我使用 changeDetection onpush 调用 detectChanges()

转载 作者:太空狗 更新时间:2023-10-29 18:23:43 26 4
gpt4 key购买 nike

我有一个使用推送变化检测的 Angular 组件。组件有一个输入,在更新路由时由组件修改。如果我将输入分配给新的引用并对其进行修改,则模板中的值不会更新。我以为只要您分配了一个新对象,就会检测到更改,但除非我在 ChangeDetectorRef 上调用 detectChanges(),否则不会检测到。

@Component({
selector: 'app-nav-links',
templateUrl: './nav-links.component.html',
styleUrls: ['./nav-links.component.less'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class NavLinksComponent implements OnInit {
@Input() links: Link[] = [];

private currentPath: string;

constructor(private router: Router,
private route: ActivatedRoute,
private cdr: ChangeDetectorRef) { }

ngOnInit() {
this.router.events.subscribe(() => {
this.updateActiveRoute();
});
}

private updateActiveRoute() {
this.currentPath = this.route.snapshot.children[0].routeConfig.path;

this.links = [...this.links].map(link => {
link.active = link.url === this.currentPath;
return link;
});

// Why is this required if I am already using the spread operator?
this.cdr.detectChanges();
}
}

最佳答案

每当浏览器事件(或 Angular 事件)发生时,就会进行更改检测。在这种情况下,发生变化检测。然而,问题是来自父组件的原始引用实际上并没有改变(从子组件的 Angular 来看它确实改变了)。

换句话说,通过覆盖组件内的@Input() 参数,您实际上是在打破父组件与子组件的输入参数之间的绑定(bind)。

根据更改检测的工作方式,从上到下检查引用,当引用似乎没有更改(从父组件的 Angular 来看)时,组件未更新也就不足为奇了。

为了保持绑定(bind)同步,使用EventEmitter设置双向绑定(bind):

export class NavLinksComponent implements OnInit {
@Input() links: Link[] = [];
@Output() linksChange: EventEmitter<Link[]>;

constructor() {
this.linksChange = new EventEmitter<Link[]>();
}

ngOnInit() {
this.router.events.subscribe(() => {
this.updateActiveRoute();

});
}
private updateActiveRoute() {
this.currentPath = this.route.snapshot.children[0].routeConfig.path;

this.links = [...this.links].map(link => {
link.active = link.url === this.currentPath;
return link;
});
// notify the parent component that the reference has changed
this.linksChange.next(this.links);
}
}

在调用组件的模板中,设置双向绑定(bind),以便在修改内部引用时通知父组件也更新其引用:

<app-nav-links [(links)]="links" />

这样,当自上而下检查引用时,更改检测器将确定引用已更改,并为其组件正确触发更改检测(对于使用 OnPush 策略的组件应该如此)。

对于默认的变更检测器来说这不是问题,因为默认情况下,变更检测器会检查所有绑定(bind)的引用,无论@Input 引用是否已更改。

关于angular - HTML 模板不会更新,除非我使用 changeDetection onpush 调用 detectChanges(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50144949/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com