0

我试图理解回调 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,OnInit, OnChanges, SimpleChanges,Output, 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);
    }
  }

}
4

3 回答 3

4

ngOnChanges()仅当组件的输入从父组件(用@Input装饰器标记的字段)更改时才被调用。但是你有@Output字段。的想法ngOnChanges()是对父级所做的更改做出反应。

按照您的业务逻辑,您可以直接处理您想要的任何内容onSubmitPost

05.04.2021 更新答案

您将值添加到数组本身。由于指向数组的链接没有更改,ngOnChanges()因此不会捕获这些更改。但是,如果您将新链接放入组件并在父级中执行以下操作:

零件:

this.yourArrInTheParent = [...this.yourArrInTheParent];

模板:

<app-post-lis [postsToAddToList]="yourArrInTheParent"></app-post-lis>

现在您传递给输入的值已更改,您将在ngOnChanges(). 如果您更改对象的属性,对象也是如此,角度不会将其视为更改,ngOnChanges()因为它仅检测@Input()值的更改。

为了捕捉这些变化,你可以使用ngDoCheck钩子。但它很耗电,请记住不要在那里进行繁重的计算。

于 2021-04-05T05:59:24.987 回答
0

正如@Vadzim Lisakovich 已经指出的那样

ngOnChanges() 仅在组件的输入从父组件更改时才被调用

现在,问题是使用 === 运算符比较输入,即浅比较。如果您向 post 数组添加一些内容,则对数组的引用保持不变,因此不会触发任何事件。
要解决此问题,您可以实施ngDoCheck()或替换参考。

这是一个与您的问题非常相似的问题:
Angular2 更改检测:ngOnChanges not fire for nested object
而且文档:
https ://angular.io/guide/lifecycle-hooks#docheck

于 2021-04-05T14:47:14.343 回答
0

我认为你的做法是正确的。只是您缺少实现 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);
    }
  }
}
于 2021-04-05T14:34:26.383 回答