OnChanges не срабатывает при частичном изменении объекта - PullRequest
0 голосов
/ 20 мая 2018

У меня проблемы с триггерами жизненного цикла 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

<code><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}}
ParamNumber
{{paramNumber | json}}

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);
  }
}

Отказ от ответственности: эта проблема является частью более серьезной проблемы, и я пыталсявыделить основной вопрос.Поэтому, пожалуйста, не вдавайтесь в подробности, речь идет о ловушке жизненного цикла и многомерном объекте.

Ответы [ 2 ]

0 голосов
/ 20 мая 2018

Обобщая все предложения, похоже, что разделение свойств объекта на отдельные переменные является лучшим решением:

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);
}
0 голосов
/ 20 мая 2018

Это типичный угловой сценарий при обнаружении изменений в свойствах объекта.Взгляните на ngDoCheck(), который можно использовать для установки пользовательской логики обнаружения изменений.

Угловой жизненный цикл будет обнаруживать только изменения ссылки на объект.Потому что почему нет?Выполнение глубокого сравнения равных объектов может привести к снижению производительности!

Что вы можете сделать -

  1. Заменить объект новым экземпляром.Например, используйте Object.assign.
  2. Поместите пользовательскую логику обнаружения изменений в метод ngDoCheck().
...