2

我在触发 Angular(6) 的onChanges生命周期挂钩时遇到问题。在将参数从组件发送到指令时,我想挂钩更改。

触发器完美地适用于一维变量,而对象未正确触发。特别是如果多维对象的一部分被传输到子指令。至少它有效,但OnChange钩子只触发一维变量。

仔细查看 StackBlitz,我在其中提供了一个可执行示例。介意打开控制台,看看,触发了哪个生命周期: https ://stackblitz.com/edit/angular-vhaews

app.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
  public paramNumber;
  public paramObject;

  ngOnInit() {
    this.paramObject = {
      x: 10,
      y: 10
    };
    this.paramNumber = 42;
  }
}

app.component.html

<div appCanvas [paramObject]="paramObject" [paramNumber]="paramNumber"></div>

ParamObject X
<input name="paramObject.x" type="number" [(ngModel)]="paramObject.x"/>
<br>
ParamObject Y
<input name="paramObject.y" type="number" [(ngModel)]="paramObject.y"/>
<pre>{{paramObject | json}}</pre>

ParamNumber
<input name="paramNumber" type="number" [(ngModel)]="paramNumber"/>
<pre>{{paramNumber | json}}</pre>

canvas.directive.ts

import { Directive, ElementRef, Input, OnInit, OnChanges } from '@angular/core';

@Directive({
  selector: '[appCanvas]'
})
export class CanvasDirective implements OnInit, OnChanges {

  @Input() private paramObject;
  @Input() private paramNumber;

  ngOnChanges() {
    console.log(`changed object`, this.paramObject);
    console.log(`changed number`, this.paramNumber);
  }

  ngOnInit() {
    console.log(`changed object`, this.paramObject);
    console.log(`changed number`, this.paramNumber);
  }
}

免责声明:这个问题是一个更大问题的一部分,我试图找出主要问题。所以请不要看太多细节,它实际上是关于生命周期钩子和多维对象。

4

2 回答 2

0

这是检测对象属性变化时的典型角度场景。看一下ngDoCheck(),可以用来放自定义变更检测逻辑。

Angular 生命周期只会检测对象引用的变化。因为为什么不呢?进行深度对象等于比较可能会影响性能!

你能做的是——

  1. 用新实例替换对象。例如,使用Object.assign.
  2. 将自定义更改检测逻辑放入ngDoCheck()方法中。
于 2018-05-20T14:47:49.417 回答
0

总结所有建议,看起来将对象属性拆分为单个变量是最好的解决方案:

app.component.html

<input name="canvasParam.x" type="number" [(ngModel)]="canvasParam.x"/>

canvas.directive.ts

private param;

@Input() private paramX;
@Input() private paramY;


ngOnChanges() {
  this.param = {
    x: this.paramX,
    y: this.paramY
  };
  console.log(`changes`, this.param);
}
于 2018-05-20T15:20:31.497 回答