问题描述
我试图理解回调 ngOnChanges() 所以我创建了下面发布的例子。但是在编译时尽管有接口 Post 分别具有属性 title 和 content 的值,但是,我没有收到来自 ngOnChanges 的任何日志
请告诉我如何正确使用
app.component.ts:
import { Component,OnInit,OnChanges,SimpleChanges,Output,EventEmitter } from '@angular/core';
export interface Post {
title:string;
content:string;
}
@Component({
selector: 'app-post-create',templateUrl: './post-create.component.html',styleUrls: ['./post-create.component.css']
})
export class PostCreateComponent implements OnInit {
@Output() post : Post;
@Output() onPostSubmittedEvtEmitter: EventEmitter<Post> = new EventEmitter<Post>();
constructor() {
this.post = {} as Post;
}
ngOnInit(): void {
}
ngOnChanges(changes: SimpleChanges) {
for (let changedProperty in changes) {
console.log("ngOnChanges->: changes[changedProperty].prevIoUsValue: " + changes[changedProperty].prevIoUsValue);
console.log("ngOnChanges->: changes[changedProperty].currentValue):" + changes[changedProperty].currentValue);
}
}
onSubmitPost(post: Post) {
this.post = {
title: this.post.title,content: this.post.content
};
this.onPostSubmittedEvtEmitter.emit(this.post);
console.log("onSubmitPost->: post.title: " + post.title);
console.log("onSubmitPost->: post.content:" + post.content);
}
}
更新 05.04.2021
按照建议,我添加了 ngOnChanges 以观察使用 Input 装饰器注释的属性的变化,如下所示:
@input() postsToAddToList: Post[] = [];
现在,当我编译代码时,我添加了一些值,我从 ngOnChanges 收到以下日志:
ngOnChanges->: changes[changedProperty].prevIoUsValue: undefined
post-list.component.ts:20 ngOnChanges->: changes[changedProperty].currentValue):
但问题是当我不断添加更多值时,我没有收到来自 ngOnChanges 的任何日志 请让我知道为什么尽管我不断添加更多值导致更改用@Input 装饰的对象的内容??!
post-list.component.ts:
import { Component,Input,EventEmitter } from '@angular/core';
import { Post } from '../post-create/post-create.component';
@Component({
selector: 'app-post-list',templateUrl: './post-list.component.html',styleUrls: ['./post-list.component.css']
})
export class PostListComponent implements OnInit {
constructor() {}
@input() postsToAddToList: Post[] = [];
ngOnInit(): void {}
ngOnChanges(changes: SimpleChanges) {
for (let changedProperty in changes) {
console.log("ngOnChanges->: changes[changedProperty].prevIoUsValue: " + changes[changedProperty].prevIoUsValue);
console.log("ngOnChanges->: changes[changedProperty].currentValue):" + changes[changedProperty].currentValue);
}
}
}
解决方法
ngOnChanges()
仅在组件的输入从父组件(标有 @Input
装饰器的字段)更改时才被调用。但是您有 @Output
字段。 ngOnChanges()
的想法是对父级所做的更改做出反应。
按照您的业务逻辑,您可以直接在 onSubmitPost
中处理您想要的任何事情。
回答 2021 年 4 月 5 日更新
您向数组本身添加值。由于指向数组的链接未更改,因此 ngOnChanges()
不会捕获这些更改。但是,如果您将新链接添加到组件并在父组件中执行以下操作:
组件:
this.yourArrInTheParent = [...this.yourArrInTheParent];
模板:
<app-post-lis [postsToAddToList]="yourArrInTheParent"></app-post-lis>
现在您传递给输入的值已更改,您将在 ngOnChanges()
中看到更改。如果您更改对象的属性,则对象也是如此,angular 不会将其视为 ngOnChanges()
的更改,因为它仅检测 @Input()
值的更改。
为了捕捉这些变化,您可以使用 ngDoCheck
钩子。但它很耗电,切记不要在那里进行繁重的计算。
我认为您的做法是正确的。只是您缺少实现 onChanges 类。在最新的 Angular 版本中,它会直接引发错误,但在旧版本中则不会。
试试这个。
export class PostListComponent implements OnInit,OnChanges{
constructor() {}
@Input() postsToAddToList: Post[] = [];
ngOnInit(): void {}
ngOnChanges(changes: SimpleChanges) {
for (let changedProperty in changes) {
console.log("ngOnChanges->: changes[changedProperty].previousValue: " +
changes[changedProperty].previousValue);
console.log("ngOnChanges->: changes[changedProperty].currentValue):" +
changes[changedProperty].currentValue);
}
}
}
,
正如@Vadzim Lisakovich 已经指出的
ngOnChanges() 仅在组件的输入从 父组件
现在,问题是使用 === 运算符比较输入,即浅比较。如果你向 post 数组添加一些东西,对数组的引用保持不变,因此不会触发任何事件。
要解决此问题,您可以实施 ngDoCheck()
或替换引用。
这是一个与您非常相似的问题:
Angular2 change detection: ngOnChanges not firing for nested object
原因是文档:
https://angular.io/guide/lifecycle-hooks#docheck