【问题标题】:ngOnChanges does not work when value is passed from parent to child当值从父级传递给子级时,ngOnChanges 不起作用
【发布时间】:2020-01-09 03:29:03
【问题描述】:

为什么即使child_message 的值发生变化,ngOnChanges 也不会被触发?我看到当值从父级传递给子级时,ngDocheck() 被触发。但是它会被触发多次,不仅是在传递值时,而且在初始化组件时也是如此。我想要在初始化后更改值时触发的东西。

ParentComponent.ts

import { Component, OnInit,ViewChild,AfterViewInit, OnChanges, Input } from '@angular/core';
import { ChildComponent } from '../child/child.component';

@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.css']
})
export class ParentComponent implements OnInit,OnChanges{
  parent_message = "parent talking";
  @Input() clicked:boolean =false;

  constructor() { }

  ngOnInit(){
    //subscribing to message !!
    //this.data.currentMesssage.subscribe(message => this.message =message)
  }
  ngOnChanges(){
    console.log("change occured")
  }
  onClick(){
    this.clicked = true;
  }
}

ParentComponent.html

   <h1>Parent </h1>
Message:{{message}}
<button (click)='onClick()'>Send Message</button> 
<div *ngIf="clicked; else notclicked">
    <app-child  [childMessage]="parent_message"> </app-child>
</div>
<ng-template #notclicked>
    <app-child> </app-child>
</ng-template>

ChildComponent.ts

    import { Component, OnInit ,Input, Output,EventEmitter,OnChanges,DoCheck} from '@angular/core';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css'],
})
export class ChildComponent implements OnChanges, DoCheck{
  @Input() childMessage: string ="child here ";
  //@Output()messageEvent = new EventEmitter<string>();
  constructor() { }
  ngOnChanges(){
    console.log("change occured");
  }
  ngDoCheck(){
    console.log("ngDoCheck");
  }
}

ChildComponent.html

   <h1>Child</h1>
Say:{{childMessage}}

【问题讨论】:

  • 如果我没记错的话,如果值被改变而不是每次都会触发 ngOnchanges。

标签: angular


【解决方案1】:

如果你想将消息从孩子传递给父母,你需要像这样实现

  @Output()  // in child class
  nextStep = new EventEmitter();
  // you can call with data in some function like on click oo input changed
  this.nextStep.emit({key: 'value'});

在您的父组件中,您可以从 $event 对象中获取值

<app-child  (nextStep)="someParentFUnction($event, acc)"></app-child>

【讨论】:

    【解决方案2】:

    Angular 在检测到组件(或指令)的输入属性发生更改时调用其 ngOnChanges() 方法。

    如果您将任何属性与模板绑定并且属性的值已更改其值,则ngOnChanges() 将触发。

    我们需要记住,当绑定属性是一个对象时,ngOnChanges() 只会在您更改整个对象时触发。

    只需在您的父模板中更改这一行,它就可以正常工作。

    <app-child (messageEvent)="receiveMessage($event)"  [child_message]="message"> </app-child>
    

    【讨论】:

      【解决方案3】:

      您的代码有几个问题。

      在您的父模板中,您传递 parent_message 属性 bu,该属性 bu 在 ParentComponent 中不存在

      <app-child (messageEvent)="receiveMessage($event)" [child_message]="parent_message"> </app-child>
      //                                                                  ^^^^^^^^^^^
      //                                                                  this needs to be "message" property of ParentComponent
      

      又在同一行:

      <app-child (messageEvent)="receiveMessage($event)" [child_message]="parent_message"> </app-child>
      //                                                   ^^^^^^^^^^^
      //                                                   this needs to be "childMessage" property of ChildComponent
      

      正如official docs 中所述,ngOnChanges@Input 等数据绑定属性发生更改后被触发。因此它不会触发。

      【讨论】:

        【解决方案4】:

        实现有两个错误 - 价值变化没有发生 - 值未正确传递给子组件 你可以看到示例实现只是参考 https://angular.io/guide/component-interaction

        【讨论】:

          【解决方案5】:

          尝试改用ngDoCheck() 生命周期挂钩。

          在每次更改检测运行期间都会调用此挂钩。

          export class ParentComponent implements OnInit, DoCheck {
                message = "parent talking";  
          
                ngOnInit(){ }
          
                ngDoCheck(){
                  console.log("change occured")
                }
          
                receiveMessage($event){
                  this.message = $event;  
                }
              }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-12-04
            • 1970-01-01
            • 2021-02-09
            • 1970-01-01
            • 1970-01-01
            • 2018-09-17
            • 1970-01-01
            相关资源
            最近更新 更多