Vasilev
Vasilev

Reputation: 87

how to change variables in different components

I have two components - one mainComponent, one MenuComponent. from MenuComponent, I want to change variable in mainComponent.

import { Injectable, Component, OnInit, NgZone } from '@angular/core';

@Injectable()
@Component({
  selector: 'app-componentmain',
  templateUrl: './main.component.html',
  styleUrls: ['./main.component.css']
})
export class ComponentMainContent {
  public selectedGroup : any;

in menu component:

import { ComponentMainContent } from '../main/main.component';
@Component({
..
providers: [ComponentMainContent]
..

export class MenuListItemComponent implements OnInit {
constructor(private ComponentMain: ComponentMainContent,

..
showGroup(item: NavItem){
     this.ComponentMain.selectedGroup = 'test'; - nothing is happening
  }

in main component.html:

{{selectedQmgr}}

can you tell me what i am missing. thank you!

Upvotes: 1

Views: 1355

Answers (2)

Keith Otto
Keith Otto

Reputation: 5178

I think there's a few ways to tackle this. I don't use the method you are attempting much so I can't really comment on what might be going on, although I think you should be able to inject the parent component into the child. The other two methods I have used are:

  1. Create a service that gets injected into both and have the shared data stored in there. Probably as a BehaviorSubject or some other alternative from Rxjs that can emit the values.
  2. Create an @Output EventEmitter in the child component that you can emit the value through, then bind to it in the template of your parent component.

Edit: Adding an example of the EventEmitter option since Muhammed already posted an example of a shared service.

@Component({
  selector: 'menu-item-component',
  ... // omitted properties
})
export class MenuItemComponent {
  @Output() groupSelected: EventEmitter<string> = new EventEmitter<string>();

  constructor() {}

  showGroup(item: NavItem){
     //this.ComponentMain.selectedGroup = 'test'; - nothing is happening
     this.groupSelected.emit('test'); //Emit whatever value you want here.
  }
}

Now in your main component (and this is assuming that the menu items are direct children) somewhere in your html template file you'd have:

<menu-item-component (groupSelected)="callbackFunction($event)">Sample</menu-item-component>

callbackFunction() would be a function on your main component that would be passed the value emitted from the menu item.

@Component({
  selector: 'main-component',
  ... // omitted properties
})
export class MainComponent {
  selectedGroup: string = null;
  constructor() {}

  callbackFunction(group: string) {
    //Do something with the value here.
    this.selectedGroup = group;
  }
}

Upvotes: 1

Muhammed Albarmavi
Muhammed Albarmavi

Reputation: 24424

just create a shared service and inject this service in the components and whean you change any property of that service will reflect to other component because it's the same service.

@Injectable({
  providedIn:'root'
})
export class DataService {

  private currentValue : number = 0;

  update() { 
    this.currentValue++;
  }

  get selectedValue(){
    return this.currentValue
  }

}

demo 🚀

Upvotes: 1

Related Questions