【问题标题】:Angular - how to pass callback in menu item on parent component menuAngular - 如何在父组件菜单的菜单项中传递回调
【发布时间】:2019-11-18 23:28:30
【问题描述】:

我想在我的应用栏中有一个菜单,可以从子组件中获取其菜单项。我正在使用 Angular 材质“mat-menu”,并且能够显示菜单项,但似乎无法触发子组件上的关联功能。

app.component.html(父级):

  <div>
    <mat-toolbar style="display: flex; flex-direction: row; justify-content: space-between; margin-bottom: 12px">
      <div>
        <button type="button" mat-icon-button id="btnMore" [matMenuTriggerFor]="appMenu" [matMenuTriggerData]="menuData">
          <mat-icon>more_horiz</mat-icon>
        </button>
        <mat-menu #appMenu="matMenu" xPosition="before">
            <ng-template matMenuContent let-aliasMenuItems="menuItems">
              <button mat-menu-item *ngFor="let item of aliasMenuItems" (click)="handleMenuAction(item.action)">
                {{item.text}}
              </button>
            </ng-template>
        </mat-menu>
      </div>
    </mat-toolbar>
  </div>
  <div>
    <router-outlet></router-outlet>
  </div>

这里是 app.component.ts(父级)。它从 appService 组件中检索菜单数据。它还(应该)执行回调。

  ngOnInit() {
    this.appService.getMenuData().subscribe(menuData => this.menuData = menuData);
  }

  handleMenuAction(action: Function) {
      action();
  }

这是子组件“company.component.ts”,它将其菜单项传递给 app.service,以便 app.component 可以检索它们。请注意,menuData 是一个对象,其中包含 string 类型的对象数组和回调 function

  ngOnInit(): void {

    this._appService.setMenuData({
      menuItems: [
        {text: "Add Company", action: this.addCompany}
    ]});
  }

  addCompany(): void {
    this._router.navigate(['/company', 0])
  }

由于某种原因,我的 Chrome 开发工具中没有显示点击事件处理程序。我希望通过菜单点击来调用函数,而不仅仅是执行导航。

可能有更好的方法来解决这个问题。如果是这样,请提供一个示例的链接。 TIA。

编辑:Stackblitz 位于 https://stackblitz.com/edit/angular-nbzoe6

【问题讨论】:

标签: javascript angular angular-material


【解决方案1】:

更新答案 根据你的stackblitz

您只需要将子组件的this 绑定到新的菜单操作,以便在您决定调用菜单操作时在子范围内运行

类似这样的:

company-list.component.ts

  ngOnInit(): void {
    this._appService.setMenuData({
      menuItems: [
        {text: "Add Company", action: this.addCompany.bind(this)}
    ]});
  }

旧答案 您可以在 appService 中创建 menuItems$ observable 并在 app.component.ts 中订阅它,然后从子组件中将新的 menuItems 添加到此 observable 中,app.component 中的 menuItems 将具有新值

类似的东西

appService.ts


class AppService {
  // ...
  menuItems$: BehaviourSubject<any[]> = new BehaviourSubject([]);
  constrcutor() {}

  // ...
}

app.component.ts

class AppComponenet {
  // ...
  menuItems: any[] = [];
  constrcutor(private appService: AppService) {}

  ngOnInit() {
    // ...
    this.appService.menuItems$.subscribe(newMenu => {
      this.menuItems = newMenu;
    });
  }
}

child.compnenet.ts

class ChildComponenet {
  // ...
  constrcutor(private appService: AppService) {}

  ngOnInit() {
    // ...
    this.appService.menuItems$.new(['home', 'about']);
  }
}

【讨论】:

  • 感谢您的回复。但是,我相信点击事件未触发的问题仍然存在。您的解决方案只是传递数组而不是包含数组的对象。
猜你喜欢
  • 1970-01-01
  • 2020-07-29
  • 1970-01-01
  • 1970-01-01
  • 2019-03-23
  • 1970-01-01
  • 2016-12-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多