Как работает двусторонняя привязка в Angular 2?

Я пытаюсь использовать двустороннюю привязку между двумя моими компонентами (родительский и дочерний компоненты) и пытаюсь обнаружить вызванные этим изменения в ngOnChanges обоих компонентов. Я могу запустить ngOnChanges дочернего компонента (тестовый компонент), изменив свойство ввода / вывода родительского компонента (компонент приложения). Однако я не могу вызвать ngOnChanges родительского компонента, изменив свойство с двусторонней привязкой в ​​дочернем компоненте.

Рабочий Plunker можно найти здесь: https://plnkr.co/edit/AGh6EM9l9ENMufb9JWPW?p=preview

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

@Component({
  selector: 'my-app',
  template: `<h1>Hello {{name}}</h1>
              <h3>Two Way Parent - {{twoWaySend}} </h3>

              <button (click) =  "oneWayButtonPressed()">Increase oneWay from Parent</button>
              <button (click) = "twoWayButtonPressed()">Increase TwoWay from Parent</button>  
                <test-component [oneWayReceive] = 'oneWaySend' 
              [(twoWayReceive)] = 'twoWaySend'></test-component>`
})
export class AppComponent implements OnChanges{ 
  name = 'Angular';
  oneWaySend = "You shall pass";
  twoWaySend = "You shall both ways";
  counter:int = 0;
  negativeCounter:int = 0;
  oneWayButtonPressed() {
    this.oneWaySend = `${this.oneWaySend} ${++this.counter}`;
  }
  twoWayButtonPressed() {
    this.twoWaySend = `${this.twoWaySend} ${--this.negativeCounter}`;
  }
  ngOnChanges() {
    console.log('ngOnchange Parent ' + this.twoWaySend);
  }
}



@Component({
  selector: 'test-component',
  template: `<h1>TestComponent {{name}}  {{oneWayReceive}}</h1>
            <h3>Two Way Child - {{twoWayReceive}}</h3>  
            <button (click) = "twoWayButtonPressed()">Change Two Way from Child</button>`
})
export class TestComponent implements OnChange {
  @Input() oneWayReceive;
  @Input() twoWayReceive;
  @Output() twoWayReceiveChange: EventEmitter<string> = new EventEmitter<string>();
  name = 'Angular';
  negativeCounter = 0;
  ngOnChanges() {
    console.log(`OneWayReceive ${this.oneWayReceive}   TwoWayReceive ${this.twoWayReceive}`);
  }
  twoWayButtonPressed() {
    this.twoWayReceive = `${--this.negativeCounter}  ${this.twoWayReceive}`;
    this.twoWayReceiveChange.emit(this.twoWayReceive);
  }
}

person Jayant Pareek    schedule 09.06.2017    source источник


Ответы (3)


ngOnChanges вызывается только тогда, когда родительский компонент передает другое значение для входа компонента. Вам просто не следует ожидать вызова метода ngOnChanges родительского компонента, поскольку он не имеет ввода или какого-либо родительского компонента.

person JB Nizet    schedule 09.06.2017

Просто ты не можешь

«Я не могу вызвать ngOnChanges родительского компонента, изменив свойство с двусторонней привязкой в ​​дочернем компоненте»

вы можете обнаружить это только от родителя к потомку, если вы хотите передать измененное значение или событие от дочернего к родителю, вы должны использовать @Outpput или EventTrigger via Service

person Vivek Doshi    schedule 09.06.2017
comment
Но поскольку родительский twoWaySend обновляется при изменении дочернего компонента, разве вы не думаете, что должно быть событие для фиксации этого изменения? - person jitenagarwal19; 09.06.2017
comment
@ jitenagarwal19, да, есть способ захватить его, но не через ngOnChanges. Вы можете сделать это с помощью @Outpput или EventTrigger через службу - person Vivek Doshi; 09.06.2017
comment
Было бы очень полезно, если бы вы могли разветвить plunkr и продемонстрировать его. - person jitenagarwal19; 09.06.2017
comment
Извините @ jitenagarwal19, сейчас это займет время, я могу помочь вам позже, но ответ на этот вопрос - нет, вы не можете сделать это таким образом. - person Vivek Doshi; 09.06.2017

В документации по Angular указано, что ngOnChanges вызывается:

когда Angular (повторно) устанавливает свойства ввода с привязкой к данным

Если вы хотите зафиксировать это обновление;

Вы можете явно использовать привязку вывода / события вместо использования [()].

[twoWayReceive]="twoWaySend" (twoWayReceiveChange)="twoWaySendChange($event)"

И обработчик изменения вывода в вашем родительском компоненте будет

toWaySendChange(value: string) {
  this.twoWaySendChange = value;
  // do things that you wanted to do in ngOnChanges
}
person harunurhan    schedule 24.08.2017