首页 > 解决方案 > 视图完全加载后如何从另一个组件调用方法?

问题描述

我在“标题组件”中使用来自 Angular Material 的 MatMenu。我只需要在某些条件下打开菜单。然而这个方法只在 ngAfterViewInit() 中起作用,在视图被加载之后。

export class HeaderComponent implements AfterViewInit {
  @ViewChild('triggerCart') trigger: MatMenuTrigger;

  ngAfterViewInit() {
    this.openMenu();
  }

  openMenu() {
    this.trigger.openMenu();
  }
}
<button mat-button 
        [matMenuTriggerFor]="shoppingCartMenu" 
        #triggerCart="matMenuTrigger" 
        (menuOpened)="isOpened($event)" 
        (mouseenter)="largeScreen ? triggerCart.openMenu() : ''">
</button>

我需要从另一个组件调用此方法,但菜单触发器在 ngAfterViewInit 之外未定义。

<button mat-stroked-button
        (click)="someMethod()">
</button>

export class ProductDetailComponent {
  @ViewChild(HeaderComponent) header: HeaderComponent;
  
  someMethod() {
    this.header.openMenu();
  }
}

加载 Header 组件后,如何实现组件之间的通信?

标签: angulartypescriptangular-material

解决方案


这是一个方法示例(但不一定是最好的方法)。这是为了让人们了解组件之间的交互。

StackBlitz

产品组成

export class ProductComponent {
  clickBehavior = new BehaviorSubject(null);

  click() {
    this.clickBehavior.next(1);
  }
}

产品标记

<my-header [openMenu]="clickBehavior"></my-header>
<div>
  <button (click)="click()">Click</button>
</div>

标头组件

export class HeaderComponent implements AfterViewInit {
  @ViewChild('trigger') trigger: MatMenuTrigger;
  @Input() openMenu: Observable<any>;

  ngAfterViewInit() {
    this.openMenu.subscribe(value => {
      if (value) {
        this.trigger.openMenu();
      }
    });
  }
}

标题标记

<button mat-button
        [matMenuTriggerFor]="menu"
        #trigger="matMenuTrigger">Menu</button>
<mat-menu #menu="matMenu">
  <button mat-menu-item>Item 1</button>
  <button mat-menu-item>Item 2</button>
</mat-menu>

这个想法是触发 Header 组件的 Input,这是使用 Product 组件中的 BehaviorSubject 完成的。

参考:


推荐阅读