【问题标题】:Angular - How can I toggle the visibility of an element in a component from another component?Angular - 如何从另一个组件切换组件中元素的可见性?
【发布时间】:2019-03-27 12:21:08
【问题描述】:

我的 Angular 应用中有以下场景:

当我有路由/ 时可见的组件MainDashboardComponent。显然我的app.component.html 文件中有<router-outlet> 标签,如下所示:

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

如您所见,我有一个 SideMenuComponent 我曾经在我的所有路线上都有一个侧面菜单。在MainDashboardComponent 中,我有一个方法,由于某种原因需要切换位于侧面菜单上的聊天元素。 在SideMenuComponent 内部,我有一个方法可以处理聊天元素的可见性切换,它可以按预期工作。如何从我的MainDashboardComponent 调用此方法并从那里切换聊天元素?

我尝试了没有成功

我尝试将SideMenuComponent 注入到我的MainDashboardComponent 中,但是尽管调用了toggleChat() 方法,但该元素并没有改变它的可见性。看起来我猜想我有一个相同组件的多个实例......

你能帮我解决这个问题吗?谢谢!

MainDashboardComponent

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

@Component({
  selector: 'app-main-dashboard',
  templateUrl: './main-dashboard.component.html',
  styleUrls: ['./main-dashboard.component.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.component.html',
  styleUrls: ['./side-menu.component.scss']
})
export class SideMenuComponent implements OnInit {

  showChat: boolean;

  constructor() {
    this.showChat = false;
  }

  ngOnInit() {
  }

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

}

【问题讨论】:

  • 你能添加完整的代码吗
  • 哪个是你的 MainDashboardComponent ? MainDashboardComponent 是路由之一吗?
  • 我已经更新了我的问题:)
  • 您可以将toggleChat() 方法设置为静态和setFocus(id) { SideMenuComponent.toggleChat()
  • 你也可以利用 rxjs BehaviorSubject

标签: javascript angular angular-components


【解决方案1】:

不同组件之间的通信有不同的方式。

  • 如果你想在父子组件之间进行通信,你可以使用EventEmitter从子组件发出事件并在你的父组件中处理事件
  • 如果你想在任何组件之间进行通信,你可以使用Service并借助EventEmitter或Subject/BehaviorSubject实现通信

在您的情况下,我们可以创建一个服务 myService.ts 并声明和 eventEmitter

.service.ts

@Injectable()
export class AppCommonService {

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

}

ma​​inDashboard.component.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.component.ts

constructor(private myService : myService){}

chatStatus : boolean = false;

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

【讨论】:

  • 伟大而简单的解决方案!正是我想要的!我从来没有遇到过这样的案例,也从来没有想过如何做这种事情,从现在开始会记住它:) 谢谢 Sarthak!
【解决方案2】:

通常这是服务的域!

  • 只需创建一个服务并添加“showCat”属性即可。
  • 将服务注入到两个组件中
  • 将 SideMenuComponent 更改为:

    toggleChat() {
        this.myService.showChat = !this.myService.showChat;
    }
    
  • 改变 MainDashboardComponent,也可以使用 this.myService.showChat 来显示/隐藏你的聊天窗口

服务 TS

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

主仪表板组件

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

SideMenuComponent

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

【讨论】:

    【解决方案3】:

    在这种情况下,您可以有效地使用子与父通信。您需要在 SideMenuComponent 中使用 angular 的 EventEmitter 创建自定义事件,并在 MainDashboardComponent 中使用它。

    所以,这里有一些代码可以帮助你 -

    // SideMenuComponent
    import { Component, OnInit } from '@angular/core';
    @Component({
        selector: 'app-side-menu',
        templateUrl: './side-menu.component.html',
        styleUrls: ['./side-menu.component.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.component.scss']
    })
    export class MainDashboardComponent implements OnInit {
    
        constructor() { }
    
        ngOnInit() { }
    
        setFocus(event) {
            // check for required input value 
            console.log(event);
        }
    }
    

    如果需要,请参阅这些教程 - https://dzone.com/articles/understanding-output-and-eventemitter-in-angular, https://angular-2-training-book.rangle.io/handout/components/app_structure/responding_to_component_events.html

    【讨论】:

      猜你喜欢
      • 2021-01-19
      • 2020-04-10
      • 2021-11-02
      • 1970-01-01
      • 1970-01-01
      • 2018-02-20
      • 1970-01-01
      • 1970-01-01
      • 2016-10-14
      相关资源
      最近更新 更多