Подтвердить что ты не робот

Angular 2 события, захватывающие между компонентами сестры

Я только начал изучать Angular 2, и это мой первый вопрос о переполнении стека, поэтому здесь идет...

У меня есть внешний компонент с двумя вложенными внутренними компонентами. У меня есть кнопка в InnerComponent1, которая при нажатии вызывает событие, которое получает внешний компонент, который затем передает значение (всегда true) в InnerComponent2. InnerComponent2 отображается (* ngIf) на основе этого значения.

Он работает.

Buuuut.. InnerComponent2 имеет кнопку, которая при щелчке делает это значение ложным, которое скрывает компонент.

Это тоже работает.

Но как только я скрою InnerComponent2, кнопка в InnerComponent1, которая отображает InnerComponent2, больше не работает. Я не вижу никаких ошибок, и я подтвердил, что внешний компонент все еще принимает события.

Здесь plnkr, который показывает сценарий: http://plnkr.co/edit/X5YnNVm0dpFwA4ddv4u7?p=preview

Любые мысли?

Большое спасибо.

Внешний компонент

//our root app component
import {Component} from 'angular2/core';
import {Inner1Component} from 'src/inner1';
import {Inner2Component} from 'src/inner2';

@Component({
  selector: 'my-app',
  providers: [],
  template: `
    <p>OuterComponent</p>
    <inner1 (show2)="show2Clicked = $event"></inner1>
    <inner2 [showMe]="show2Clicked"></inner2>
  `,
  directives: [Inner1Component, Inner2Component]
})
export class App {
  show2Clicked: boolean;
}

InnerComponent1

import {Component, EventEmitter, Output} from 'angular2/core'

@Component({
  selector: 'inner1',
  providers: [],
  template: `
    <p>inner1</p>
    <button (click)="showInner2()">Show inner2</button>
  `,
  directives: []
})
export class Inner1Component {
  @Output() show2 = new EventEmitter<boolean>();

  showInner2() {
    this.show2.emit(true);
  }
}

InnerComponent2

import {Component, Input} from 'angular2/core'

@Component({
  selector: 'inner2',
  providers: [],
  template: `
    <div *ngIf="showMe">
      <p>Inner2</p>
      <button (click)="showMe = false">Cancel</button>
    </div>
  `,
  directives: []
})
export class Inner2Component {
  @Input() showMe: boolean;
}
4b9b3361

Ответ 1

Значения showMe и shwo2Clicked не синхронизируются.

Я добавил и EventEmitter в <inner2> и изменил

<inner2 [showMe]="show2Clicked"></inner2>

к

<inner2 [(showMe)]="show2Clicked"></inner2>

Я думаю, теперь он работает так, как вы ожидаете

http://plnkr.co/edit/tXzr3XgTrgMWMVzAw8d7?p=preview

Обновление

Связывание [showMe] работает только в одном направлении. Если для параметра show2Clicked установлено значение true, для параметра showMe будет установлено значение true. Отмените настройки showMe назад на значение false. Если затем show2Clicked снова установлено на true, ничего не происходит, потому что он уже true и showMe не обновляется. С EventEmitter и двусторонним сокращением привязки [(showMe)], show2Clicked также устанавливается на false, когда showMe установлено на false, а установка его на true на самом деле является изменением, которое распространяется вниз хотя привязка.

[(showMe)]="show2Clicked" является сокращением для [showMe]="show2Clicked" (showMeChange)="show2Clicked=$event", и стенография работает только тогда, когда вывод имеет то же имя, что и вход, но с дополнительным Change

Ответ 2

У меня была такая же проблема, переключив форму, нажав кнопку из компонента родного брата. Мое решение состояло в том, чтобы использовать общую службу.

поэтому в компоненте 1:

<button (click)="showMessageForm()" >
showForm = true;
showMessageForm() {
    this.messageService.switchMessageForm(this.showForm);
    this.showForm = !this.showForm;
}

в сервисе:

switchMessageFormEvent = new EventEmitter<boolean>();
switchMessageForm(bSwitch:boolean) {
    this.switchMessageFormEvent.emit(bSwitch);
}

в компоненте 2:

ngOnInit() {
    this.messageService.switchMessageFormEvent.subscribe(
        (bSwitch: boolean) => {
            if(bSwitch) {
                $('.message-input').slideDown("normal");
            }else {
                this.myForm.reset();
                $('.message-input').slideUp("normal");
            }
        }
    );
}