Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 changing component variables on another component

Tags:

angular

How can a component change a variable on another component. Example:

I have a component app.component.ts

@Component({
    selector: 'my-app',
    template: `
    <nav *ngIf="onMain == false">
       Hello
    </nav>
    `
})

export class AppComponent{
  onMain: Boolean;

  constructor(){
      this.onMain = false;
    }
}

I have another component which I want to change onMain in my app component main.component.ts

import {AppComponent} from '../app.component';

@Component({
    selector: 'main-app',
    template: ``
})

export class MainComponent{

  constructor() {
      this.appComponent = AppComponent;
      this.appComponent.onMain = true;
    }
}

I would expect that Hello would disappear, but it doesn't. How can I have one component change the value on another component?

like image 397
ClickThisNick Avatar asked Mar 02 '16 04:03

ClickThisNick


People also ask

How do you transfer variables from one component to another?

For passing the data from the child component to the parent component, we have to create a callback function in the parent component and then pass the callback function to the child component as a prop. This callback function will retrieve the data from the child component.

How can we use one component in another component in Angular 2?

Step 1 : Import Component Objectimport { Component } from '@angular/core'; Angular 2 uses ES6 style syntax which allows to reuse code by importing them from one file to another. In the above code, we are importing Component object from @angular/core. @angular/core is included as a dependency in package.

How do you pass data from one component to another in Angular on button click?

This can be done via input binding, which passes data from one component to another, generally from parent to child. This custom input binding is created by using the @Input() decorator.


2 Answers

First of all, you have no connection between two components or maybe something is not correct in your code. If you have parent/child scenario you can use @Input,@Output of angular2. If you don't have parent/child scenario you can go with EventEmitter,SharedService of angular2.

Working demo-EventEmitter way

I have considered AppComponent is a parentComponent and MainComponent as a child component. Using SharedService & EventEmitter concepts of angular2, I'm able to hide AppComponent's part of view by clicking a button which belongs to 'MainComponent's' view.

AppComponent.ts

import {Component,bind,CORE_DIRECTIVES,OnInit} from 'angular2/core';
import {MainComponent} from 'src/MainComponent';
import {SharedService} from 'src/shared.service';
@Component({
    selector: 'my-app',
    directives:[MainComponent],
    template: `<h1>AppComponent {{onMain}}</h1>
    <div *ngIf="onMain == false">
       Hello
      <br> __________________________________<br>
    </div>

  <main-app></main-app>
    `
})

export class AppComponent implements OnInit {
  onMain: Boolean;

  constructor(ss: SharedService) {
      this.onMain = false;
      this.ss = ss;
    }



    ngOnInit() {
    this.subscription = this.ss.getEmittedValue()
      .subscribe(item => this.onMain=item);
  }

}

MainComponent.ts

import {Component,bind,CORE_DIRECTIVES} from 'angular2/core';
import {SharedService} from 'src/shared.service';
@Component({
    selector: 'main-app',

    template: `<h1> MainComponent</h1>
    <button (click)="changeName()">Change Name</button>
    `
})

export class MainComponent {



    constructor(ss: SharedService) {
      this.ss = ss;
    }

    changeName() {
      this.ss.change();
    }
}

shared.service.ts

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


@Injectable()
export class SharedService {
  @Output() fire: EventEmitter<any> = new EventEmitter();

   constructor() {
     console.log('shared service started');
   }

   change() {
    console.log('change started'); 
     this.fire.emit(true);
   }

   getEmittedValue() {
     return this.fire;
   }

} 
like image 199
Nikhil Shah Avatar answered Oct 21 '22 00:10

Nikhil Shah


If there is no relation between components (I mean parent / child), you need to use a shared service with an EventEmitter property. One component will emit an event based on it and this other component will be notified by subscribing the EventEmitter. When the event is received, this component can set a property used to show / hide the button...

  • Shared service

    @Injectable()
    export class SharedService {
      onMainEvent: EventEmitter = new EventEmitter();
    }
    

    Don't forget to define the corresponding provider in the boostrap function to be able to share the same instance of the service for the whole application: `bootstrap(AppComponent, [ SharedService ]);

  • AppComponent component

    @Component({ ... })
    export class AppComponent {
      onMain: boolean = false;
      constructor(service: MenuService) {
        sharedService.onMainEvent.subscribe(
          (onMain) => {
            this.onMain = onMain;
          }
       );
     }
    

    }

  • MainComponent component:

    export class MainComponent {
      constructor(private service: SharedService) {
      }
    
      updateOnMain(onMain):void {
        this.service.onMainEvent.emit(onMain);
      }
    }
    

These questions for more details:

  • Delegation: EventEmitter or Observable in Angular2
  • hidding button of another view angular2
like image 10
Thierry Templier Avatar answered Oct 21 '22 01:10

Thierry Templier