【问题标题】:Are child component input properties resolved before ngOnInit?子组件输入属性是否在 ngOnInit 之前解析?
【发布时间】:2020-12-13 07:09:13
【问题描述】:

我有一个父组件正在创建三个相同的子组件。孩子们有一个输入,该输入对应于一些格式化为数组的自动完成数据。但是,当我尝试在父级的 ngOnInit 中填充数组然后将其传递给其中一个子级时,子级会收到 undefined 作为数组实例。如果我尝试将 null 作为输入传递,则会发生同样的事情。

我只是想知道生命周期是否导致了这种情况,我应该使用 ngAfterInit 或其他什么来代替?

父组件

<app-alert-chip-list [autocompleteData]="targetGroupAutocomplete"></app-alert-chip-list>
<app-alert-chip-list [fArray]="alertContacts" [autocompleteData]="null"></app-alert-chip-list>
...

ngOnInit() {
    this.targetGroupAutocomplete = ['This is the first autocomplete', 'This is a second sentence that is a longer sentence than the first autocomplete', 'This'];
  }

子组件

@Input() fArray: FormArray;
  @Input() autocompleteData: string[];

  constructor(private formBuilder: FormBuilder) { }

  ngOnInit() {
    if(this.autocompleteData && this.autocompleteData.length != 0) {
      this.usesAutocomplete = true;
    }
    console.log("AC:", this.autocompleteData); //Ends up printing undefined
  }

【问题讨论】:

  • 你能在 stackblitz 中重现它吗?
  • 子组件内部从 ngOnInit 更改为 ngAfterViewInit

标签: angular


【解决方案1】:

你需要通过 ngOnchanges 观察你的孩子输入的变化

ngOnChanges(changes: SimpleChanges): void {
    for (let propName in changes) {
      let change = changes[propName];
      if (propName === "YOUR_INPUT_NAME") {
        this.YOUR_INPUT_NAME = (change.currentValue);
          // you can add whatever logic that to be executed. depend on which input is changed 
      }
    }
  }

【讨论】:

  • 为什么我需要做这么复杂的事情只是为了将输入传递给子组件?我在不同的组件中做了完全相同的事情,并且没有问题。
  • 因为你的输入值已经改变,子组件在第一次运行时只会处理初始值
  • 它并没有改变,它已经在 ngOnInit 中设置,然后传递给第一个孩子?
  • 不改了,从undefined变成父onInit生命周期中的新值
  • @TamerHussien,我认为在@Input 中使用“setters”是一种更好的方法(对我来说它更“自然”)
【解决方案2】:

我建议另一种方法:在您的输入中使用“setters”:

private _autoCompleteData: string[]; //declare a a private variable

@Input() fArray: FormArray;

@Input() set autocompleteData(value) {
  this._autoCompleteData = value; //equal the variable

  if(value && value.length != 0) { //another code that it's relationated with autoCompleteData
    this.usesAutocomplete = true;
    console.log("AC:", this.autocompleteData); //Ends up printing undefined
  }
}

get autoCompleteData() {
  return this._autoCompleteData
}

【讨论】:

    猜你喜欢
    • 2019-05-23
    • 2018-12-08
    • 2018-05-05
    • 2018-08-01
    • 2018-09-19
    • 2013-03-12
    • 2019-10-22
    • 2016-07-15
    • 1970-01-01
    相关资源
    最近更新 更多