Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 event catching between sibling components

Tags:

angular

events

I've just begun learning Angular 2, and this is my first ever Stack Overflow question, so here goes...

I have an outer component with two nested inner components. I have a button in InnerComponent1 that, when clicked, fires an event that the outer component catches, which then passes the value (always true) into InnerComponent2. InnerComponent2 is displayed (*ngIf) based on that value.

It works.

Buuuut.. InnerComponent2 has a button that, when clicked, makes that value false, which hides the component.

That works too.

But once I've hidden InnerComponent2, the button in InnerComponent1 that displays InnerComponent2 no longer works. I'm not seeing any errors and I have confirmed that the outer component is still receiving the events.

Here's a plnkr that shows the scenario: http://plnkr.co/edit/X5YnNVm0dpFwA4ddv4u7?p=preview

Any thoughts?

Thanks very much.

Outer component

//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;
}
like image 311
David Avatar asked Feb 28 '16 17:02

David


1 Answers

I had the same problem, switching a form upon clicking a button from sibling component. My solution was to use a common service.

so in component 1 :

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

in service :

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

in component 2 :

ngOnInit() {
    this.messageService.switchMessageFormEvent.subscribe(
        (bSwitch: boolean) => {
            if(bSwitch) {
                $('.message-input').slideDown("normal");
            }else {
                this.myForm.reset();
                $('.message-input').slideUp("normal");
            }
        }
    );
}
like image 84
Adel Sanhaji Avatar answered Sep 19 '22 10:09

Adel Sanhaji