【问题标题】:Angular 2 => notify a route component of an event in the app componentAngular 2 => 通知应用程序组件中的事件的路由组件
【发布时间】:2017-07-14 09:16:03
【问题描述】:

慢慢掌握 angular 2,但我在一个特定问题上走到了死胡同。

如果你有这种安排;

<parent>
    <child/>
</parent>

我可以使用@Input() 通知子级父级的更改,并让它监听更改。 我可以通过使用@Output() 和 EventEmitters 来通知父母孩子的变化。

我现在正在查看的是通知路由组件(当单击链接时动态加载的组件)主 appComponent 中发生的特定事件。请参阅下面的示例;

<app>
    <button (click)='addEntity()>Add</button>
    <router-outlet></router-outlet>
</app>

我希望能够通知加载到路由器插座中的组件该按钮已被单击。

一个使用示例是拥有多个功能(英雄/联系人/宠物等),每个功能都有自己的用于添加实体的对话框。根据所选路由,它需要通知所选功能组件(例如 ContactComponent)以显示其特定的详细组件/视图/模板(例如contact-detail.component)。

实现这一目标的最佳方法是什么?

干杯

【问题讨论】:

    标签: angular angular2-routing


    【解决方案1】:

    也有可能只使用共享服务在不同组件之间进行通信,例如通过这样的信使服务:

    MessengerService

    import { Injectable } from '@angular/core';
    import { BehaviorSubject } from 'rxjs';
    import { Observable } from 'rxjs/Rx';
    
    @Injectable()
    export class MessengerService {
        private messageSource: BehaviorSubject<boolean> = new BehaviorSubject(true); 
        public message = this.messageSource.asObservable();
        public buttonClicked(value: boolean) {
            this.messageSource.next(value);
        }
    }
    

    父组件

    export class ParentComponent {
        constructor(private messengerService: MessengerService) { }
        addEntity() {
            this.messengerService.buttonClicked(true);
        }
    }
    

    子组件

    import { Subscription } from 'rxjs/Rx';
    export class ChildComponent implements OnInit, OnDestroy {
        private messageSubscription: Subscription;
        constructor(private messengerService: MessengerService) { }
        ngOnInit() {
            this.messageSubscription = this.messengerService.message.subscribe(m => {
                // Act upon the click event
            });
        }
        ngOnDestroy() {
            this.messageSubscription.unsubscribe();
        }
    }
    

    这将是一种解耦组件并依赖信使服务的简洁方式(您可以在需要时在多个组件中订阅该服务)

    【讨论】:

    • 看来共享服务是实现这一目标的唯一真正方法。我在某处读到服务不应该使用事件发射器,这对我来说是最好的选择,因为我不是在传达状态而是意图,即 addEntity 说用户想要查看 addEntity 屏幕,它不处理可见性该屏幕的(因为它可能已经可见)。无论哪种方式都有效,只是看起来很奇怪,因为您似乎订阅了一个其值从未真正改变过的可观察对象。
    • 这为我解决了一个边缘情况问题,我真的不确定如何以一种整洁的方式解决。谢谢。
    【解决方案2】:

    如果我理解你的问题,试试这个: 在 addEntity() 方法上放置一个返回值,可以是一个字符串,或者你知道你要添加的东西的类型(英雄/联系人/宠物)。 然后在主模板上放置一个局部变量,该变量接受 addEntity() 方法的返回,如下所示:

    <button (click)='#type_added = addEntity()>Add</button>
    

    然后您可以将“#type_added”局部变量传递给其他组件,如下所示:

    <router-outlet [added] = #type_added></router-outlet>
    

    并且您必须在您的路由器出口组件 (.ts) 中声明变量“添加”到 @Output 中。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-19
    • 2019-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多