admin管理员组

文章数量:1313944

I have the following scenario in my Angular app:

A ponent MainDashboardComponent that is visible when I have the route /. Obviously I have the <router-outlet> tag in my appponent.html file, which looks like this:

<app-side-menu></app-side-menu>
<div class="main-container">
  <div class="content">
    <router-outlet></router-outlet>
  </div>
</div>

As you can see I have a SideMenuComponent I use to have a side menu on all my routes. In MainDashboardComponent I have a method that for some reason needs to toggle a chat element that is situated on the side menu. Inside the SideMenuComponent I have a method that handles the visibility toggle for the chat element and it works as expected. How can I call this method from my MainDashboardComponent and toggle the chat element from there?

What I tried with no success

I tried to inject the SideMenuComponent inside my MainDashboardComponent but, though the method toggleChat() is called, the element doesn't change it's visibility. Looks like I have a kind of multiple instance of the same ponent I guess...

Can you please help me with this? Thank you!

MainDashboardComponent

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

@Component({
  selector: 'app-main-dashboard',
  templateUrl: './main-dashboardponent.html',
  styleUrls: ['./main-dashboardponent.scss']
})
export class MainDashboardComponent implements OnInit {

  constructor() { }

  ngOnInit() {}

  setFocus(id) {
    // here I'd like to call SideMenuComponent togglechat() ... 
  }
}

SideMenuComponent

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

@Component({
  selector: 'app-side-menu',
  templateUrl: './side-menuponent.html',
  styleUrls: ['./side-menuponent.scss']
})
export class SideMenuComponent implements OnInit {

  showChat: boolean;

  constructor() {
    this.showChat = false;
  }

  ngOnInit() {
  }

  toggleChat() {
    this.showChat = !this.showChat;
  }

}

I have the following scenario in my Angular app:

A ponent MainDashboardComponent that is visible when I have the route /. Obviously I have the <router-outlet> tag in my app.ponent.html file, which looks like this:

<app-side-menu></app-side-menu>
<div class="main-container">
  <div class="content">
    <router-outlet></router-outlet>
  </div>
</div>

As you can see I have a SideMenuComponent I use to have a side menu on all my routes. In MainDashboardComponent I have a method that for some reason needs to toggle a chat element that is situated on the side menu. Inside the SideMenuComponent I have a method that handles the visibility toggle for the chat element and it works as expected. How can I call this method from my MainDashboardComponent and toggle the chat element from there?

What I tried with no success

I tried to inject the SideMenuComponent inside my MainDashboardComponent but, though the method toggleChat() is called, the element doesn't change it's visibility. Looks like I have a kind of multiple instance of the same ponent I guess...

Can you please help me with this? Thank you!

MainDashboardComponent

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

@Component({
  selector: 'app-main-dashboard',
  templateUrl: './main-dashboard.ponent.html',
  styleUrls: ['./main-dashboard.ponent.scss']
})
export class MainDashboardComponent implements OnInit {

  constructor() { }

  ngOnInit() {}

  setFocus(id) {
    // here I'd like to call SideMenuComponent togglechat() ... 
  }
}

SideMenuComponent

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

@Component({
  selector: 'app-side-menu',
  templateUrl: './side-menu.ponent.html',
  styleUrls: ['./side-menu.ponent.scss']
})
export class SideMenuComponent implements OnInit {

  showChat: boolean;

  constructor() {
    this.showChat = false;
  }

  ngOnInit() {
  }

  toggleChat() {
    this.showChat = !this.showChat;
  }

}
Share Improve this question edited Oct 23, 2018 at 9:57 Leonardo Minati asked Oct 23, 2018 at 9:49 Leonardo MinatiLeonardo Minati 3601 gold badge4 silver badges17 bronze badges 6
  • can you add full code for that – user6299088 Commented Oct 23, 2018 at 9:52
  • which is your MainDashboardComponent ? Is MainDashboardComponent one of the route? – Sarthak Aggarwal Commented Oct 23, 2018 at 9:53
  • I've update my question :) – Leonardo Minati Commented Oct 23, 2018 at 9:57
  • you can make toggleChat() method to static and in setFocus(id) { SideMenuComponent.toggleChat() – Suryan Commented Oct 23, 2018 at 10:00
  • 1 You can also take the leverage of rxjs BehaviorSubject – Suryan Commented Oct 23, 2018 at 10:13
 |  Show 1 more ment

3 Answers 3

Reset to default 7

To municate between different ponents, there are different ways.

  • If you want to municate between parent and child ponent, you can use EventEmitter to emit event from child ponent and handle the event in your parent ponent
  • If you want to municate between any ponents, you can use Service and implement munication with the help of EventEmitter or Subject/BehaviorSubject

In your case, we can create a service, myService.ts and declare and eventEmitter

.service.ts

@Injectable()
export class AppCommonService {

 toggle : EventEmitter<boolean> = new EventEmitter<boolean>()

}

mainDashboard.ponent.ts

constructor(private myService : myService){}

chatStatus : boolean = false;
ngOnInit(){
 this.myService.toggle.subscribe(status=>this.chatStatus = status);
}

toggleChat(){
 this.myService.toggle.emit(!this.chatStatus);
}

sideMenu.ponent.ts

constructor(private myService : myService){}

chatStatus : boolean = false;

ngOnInit(){
  this.myService.toggle.subscribe(status=>this.chatStatus = status);
}

Generally this is the domain of a service!

  • Just create a service and add the "showCat" property.
  • Inject the service into both ponents
  • Alter SideMenuComponent to:

    toggleChat() {
        this.myService.showChat = !this.myService.showChat;
    }
    
  • Alter MainDashboardComponent, also use this.myService.showChat to show / hide your chat window

Service TS

@Injectable()
export class MyService{
  showCat:boolean = true
}

MainDashboardComponent

toggleChat() {
   this.myService.showChat = !this.myService.showChat;
}

SideMenuComponent

chatVisiblity = this.myService.showCat //<-- bind this to the element attribute

You could efficiently use child to parent munication in this scenario. You'll need to create a custom event using angular's EventEmitter in your SideMenuComponent and use it in your MainDashboardComponent.

So, here is some code that may help you -

// SideMenuComponent
import { Component, OnInit } from '@angular/core';
@Component({
    selector: 'app-side-menu',
    templateUrl: './side-menu.ponent.html',
    styleUrls: ['./side-menu.ponent.scss']
})
export class SideMenuComponent implements OnInit {
    @Output() valueChange = new EventEmitter();
    showChat: boolean;

    constructor() {
        this.showChat = false;
    }

    ngOnInit() {
    }

    toggleChat() {
        this.showChat = !this.showChat;
        this.valueChange.emit(this.showChat);
    }

}

// MainDashboardComponent
import { Component, OnInit } from '@angular/core';
@Component({
    selector: 'app-main-dashboard',
    template: `<app-side-menu (valueChange)='setFocus($event)'></app-side-menu>`
    styleUrls: ['./main-dashboard.ponent.scss']
})
export class MainDashboardComponent implements OnInit {

    constructor() { }

    ngOnInit() { }

    setFocus(event) {
        // check for required input value 
        console.log(event);
    }
}

Refer these tutorials if required - https://dzone./articles/understanding-output-and-eventemitter-in-angular, https://angular-2-training-book.rangle.io/handout/ponents/app_structure/responding_to_ponent_events.html

本文标签: