【问题标题】:Toggle property in parent Component from Child Component in Angular2 (similar to $emit in AngularJS)从 Angular2 中的子组件切换父组件中的属性(类似于 AngularJS 中的 $emit)
【发布时间】:2016-06-13 16:03:57
【问题描述】:

我目前正在自学 Angular2,我有一个在 AngularJS 中很容易解决的实际问题,但目前我正在通过示例寻找 Angular2 的解决方案。无论如何,我有一个名为 App 的顶级组件,在该组件中我有一个应用 css 类的属性,这是用作组件模板的我的 HTML - 你可以看到我希望在哪里应用 css 类使用ngClassshowMenu 值只是一个布尔值。

<div class="navigation" role="navigation">
    <ul>
        <li><a [routerLink]="['Home]">Home</a></li>
        <li><a [routerLink]="['Mail']">Mail</a></li>
        <li><a [routerLink]="['Friends']">Friends</a></li>
        <li><a [routerLink]="['Games']">Games</a></li>
    </ul>
</div>
<!-- below is where I wish to toggle the class -->
<div class="site-wrap" [ngClass]="{'slide-right': showMenu}">
    <div class="container-fluid">
        <div class="row nav">
            <top-navigation></top-navigation>
        </div>
    </div>

    <div class="container-fluid content-gradient">
        <div class="row">
            <div class="col-md-10">
                <router-outlet></router-outlet>
            </div>
            <div class="col-md-2">
                <contacts-list></contacts-list>
            </div>
        </div>
    </div>

    <div class="container-fluid footer">
        <footer-navigation></footer-navigation>
    </div>
</div>

这里是 App 的组件代码(这里看的不多……)

export class App {

    showMenu: boolean = false;
    constructor() {
    }
    // I need to listen for the toggle somehow?
    toggleMenu():void {
        this.showMenu = !this.showMenu;
    }

}

现在您可以看到我有一个带有选择器top-navigation 的子组件。这个组件TopNavigation 在一个按钮上有一个方法,我希望在父/顶级组件中切换showMenu 的值。到目前为止,这是我的代码(只是一小部分摘录)

export class TopNavigation {

          constructor() {
            // Things happening here
          }

          toggleMenu():void {
            // I want to toggle the parent property by somekind of $emit
          }
    }

这里是组件的模板 HTML(不是全部)。

<div class="col-xs-2 col-sm-1  hidden-md hidden-lg hamburger-menu">
    <button class="btn btn-default" (click)="toggleMenu()">&#9776;</button>
</div>

在 AngularJS 中,toggleMenu 函数上有一个 $scope.$emit,在父函数中,我有一个 $scope.$on 来监听事件。我目前正在阅读关于 Angular2 中的 EventEmitters 的信息,但是如果有人有一个快速的解释/示例,我将非常感激,特别是因为我认为这是 Angular 开发人员的常见/实用的日常任务。

【问题讨论】:

  • 如果你有直接的亲子关系,我更喜欢 Günter 的回答。如果您需要从多个组件中切换值,请使用他们的答案(但使用 Observable 而不是 EventEmitter)。

标签: typescript angular eventemitter


【解决方案1】:

我可以利用定义EventEmitter 属性的共享服务。您的App 组件将订阅它,以便在TopNavigation 组件触发相应事件时收到通知。

  • 共享服务

    @Injectable()
    export class MenuService {
      showMenuEvent: EventEmitter = new EventEmitter();
    }
    

    不要忘记在 boostrap 函数中定义相应的提供者,以便能够为整个应用程序共享相同的服务实例:`bootstrap(App, [ MenuService ]);

  • App 组件

    @Component({ ... })
    export class App {
      showMenu: boolean = false;
      constructor(menuService: MenuService) {
        menuService.showMenuEvent.subscribe(
          (showMenu) => {
            this.showMenu = !this.showMenu;
          }
       );
     }
    

    }

  • TopNavigation组件:

    export class TopNavigation {
      constructor(private menuService: MenuService) {
        // Things happening here
      }
    
      toggleMenu():void {
        this.showMenu = this.showMenu;
        this.menuService.showMenuEvent.emit(this.showMenu);
      }
    }
    

查看这个问题了解更多详情:

【讨论】:

  • 太好了,我只是在阅读链接,但是在 TopNavigation 组件的发射中,我假设我不需要从 .emit() 发送任何数据 - 因为我不维护该组件中的 showMenu。但是,我知道我应该如何传递信息。同样在我的 MenuService 中,我收到错误 Generic type 'EventEmitter&lt;T&gt;' requires 1 type argument(s) 我假设我们在那里遗漏了一些东西。但你的答案正是我所需要的——我现在明白了!
【解决方案2】:

您可以使用双向绑定。

<top-navigation [(toggleMenu)]="showMenu"></top-navigation>

也许单向也可以,我不知道你的确切要求

<top-navigation (toggleMenuChange)="showMenu=$event"></top-navigation>
export class TopNavigation {
      @Output() toggleMenuChange: EventEmitter = new EventEmitter();

      // for two-way binding
      @Input() toggleMenu:boolean = false;

      constructor() {
        // Things happening here
      }

      toggleMenu():void {
        this.toggleMenu = !this.toggleMenu;
        this.toggleMenu.emit(this.toggleMenu);
      }
}

【讨论】:

    猜你喜欢
    • 2016-05-29
    • 2016-12-19
    • 2016-02-02
    • 1970-01-01
    • 2016-12-02
    • 1970-01-01
    • 2017-05-18
    • 2014-04-05
    • 2021-06-11
    相关资源
    最近更新 更多