添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information. Learn more

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
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?

You can use EventEmitter in a service. Then let AppComponent subscribe it to get the event of the change. – Hongbo Miao Mar 2 '16 at 4:15

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>
  <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;
                Where does this.subscription come from on AppComponent? I'm getting an error that the property subscription does not exist on AppComponent
– ClickThisNick
                Mar 3 '16 at 13:32
                Have you added rx.js file? look at the index.html in my plunker demo. you will find necessary referencing of required files. And if answers suits your requirement you should accept it as an answer so other may refer to it as an answer.
– micronyks
                Mar 3 '16 at 16:00
                @micronyks thanks. Can you also share the package.json? Because things are not working with latest platform and other packages please.
– Ravi Maniyar
                Oct 10 '16 at 16:52
                @RaviManiyar. please look here angular.io/docs/ts/latest/quickstart.html for latest package.json.
– micronyks
                Oct 10 '16 at 16:54

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
  • Yes you can change the variable value from one component to another one for this you have to inject the component exported class into the parent component by doing so you are able to reach each and every method and variable of injected class (component).

    import {Component} from 'angular2/core';
    @Component({
        selector: 'my-app',
        templateUrl: `myTemplate.html`,
        directive: [AppComponent2]
    export class AppComponent {
      variable1: boolean = true;
    @Component({
        selector: 'my-app2',
        templateUrl: `temp2.html`,
        providers: [AppComponent]
    export class AppComponent2 {
      constructor(private appComponent: AppComponent){ }
      Fun(){
        console.log('Function Called');
        this.appComponent.variable1 = false;
    <button (click)='Fun()'>Change Variable</button>
    {{appComponent.variable1}}
    
  • Updated as per ng6 -

    import { Component } from '@angular/core';

  • Working Example http://plnkr.co/edit/fpYFueOnkm5sa4JfG7uX?p=preview

    It will work with Angular 6? Could you please update the code if possible? Because i have tried to include @Directive for Angular 6, but no luck. – Raja Oct 8 '18 at 1:58

    If you have a parent/child relationship you can use an event emitter to flip the variable with just a couple lines of code. There is no need to write a whole shared service.

    app.component.ts

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

    main.component.ts

    import {AppComponent} from '../app.component';
    import { Output, EventEmitter } from '@angular/core';
    @Component({
        selector: 'main-app',
        template: ``
    export class MainComponent{
        @Output() observableEvent: EventEmitter<any> = new EventEmitter<any>();
      constructor() {
          this.appComponent = AppComponent;
          this.observableEvent.emit();
                    Agreed with your comment. No need to code a whole service on this case.
    – Dayron Gallardo
                    Oct 11 '19 at 22:41
            

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.

  •