如何在Angular2中的路由器插座中发出事件

时间:2016-07-15 10:12:10

标签: angular routing

我有主要的appComponent

<div class="appComponent">
<div class="row nav navbar">
    <div class="col-sm-8 text-left nav logo">Manacola</div>
    <button class="col-sm-1  col-sm-offset-1  btn btn-primary openGraph" (click)="openGraph()">Graph</button>
    <button class="col-sm-1   btn btn-primary openGraph" *ngIf="loggedIn" (click)="logout()">Logout</button>
</div>
<router-outlet ></router-outlet>

我想从另一个登录组件发出数据。 关键是当我按下#34;登录&#34; loginComponent中的按钮,我希望在*ngIf="loggedIn"appComponent设置&#39; true&#39;。 有这样的工作会很好:

<router-outlet (isLogged) = 'loggedIn = $event' ></router-outlet>   

3 个答案:

答案 0 :(得分:9)

这是一个很棒的小实用程序服务,用于在angular2应用程序中代理事件。请注意,您实际上应该只使用这种类型的事件代理在分离的组件之间进行通信(例如父母和路由器出口的子代之间)

实施例

....
import { EventBrokerService, IEventListener } "EventBrokerService";

@Component({
    selector: "my-listening-component",
    template: `
        <div *ngIf="indicator">I am On!</div>
        <div *ngIf="!indicator">I am Off!</div>
    `
})
@Injectable()
export class MyListeningComponent implements OnDestroy {
    public indicator: boolean = false;
    private _myEventListener: IEventListener;
    constructor(private _eventBroker: EventBrokerService) {
        this._myEventListener = _eventBroker.listen<boolean>("my-event",(value:boolean)=>{
             this.indicator = value;
        });
    }
    public ngOnDestroy() {
        this._myEventListener.ignore();
    }
}

@Component({
    selector: "my-sending-component",
    template: `
        <button (click)="canYouHearMe(true)>Turn me on</Button>
        <button (click)="canYouHearMe(false)>Turn me off</Button>
    `
})
@Injectable()
export class MySendingComponent {
    constructor(private _eventBroker: EventBrokerService) {
    }
    public canYourHearMe(value:boolean) {
        _eventBroker.emit<boolean>("my-event",value);
    }
}

EventBrokerService.ts文件:

import { Injectable } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';
import { Subject }    from 'rxjs/Subject';

interface IEventListener {
    ignore() : void;
}
interface IBrokeredEventBase {
    name:string;
    emit( data: any ): void;
    listen( next: (data: any) => void ): IEventListener;
}
interface IBrokeredEvent<T> extends IBrokeredEventBase  {
    emit( data: any ): void;
    listen( next: (data: any) => void ): IEventListener;
}
class EventListener implements IEventListener {
    constructor( private _subscription: Subscription ) {
    }
    public ignore() : void {
        this._subscription.unsubscribe();
    }
}

class BrokeredEvent<T> implements IBrokeredEvent<T> {
    private _subject: Subject<T>;
    constructor( public name: string ) {
        this._subject = new Subject<T>();
    }
    public emit( data: T ): void {
        this._subject.next(data);
    }
    public listen(next: (value: T) => void): IEventListener {
        return new EventListener(this._subject.subscribe( next ));
    }
}
@Injectable()
export class EventBrokerService {
    private _events: { [name: string]: IBrokeredEventBase };
    constructor() {
        this._events = {};
    }
    public register<T>(eventName: string ) : BrokeredEvent<T> {
        var event = this._events[eventName];
        if ( typeof event === 'undefined' ) {
            event = this._events[eventName] = new BrokeredEvent<T>(eventName);
        }
        return event as BrokeredEvent<T>;
    }
    public listen<T>(eventName: string, next: (value: T) => void) : IEventListener {
        return this.register<T>(eventName).listen(next);
    }
    public emit<T>(eventName: string, data: T) : void {
        return this.register<T>(eventName).emit(data);
    }
}

不要忘记将eventBrokerService注册为angular2模块中的提供程序。

答案 1 :(得分:7)

您可以在路由器出口处呈现的组件中定义@Output事件发射器。 定义路由器插座如下。

*.html
<router-outlet (activate)="onActivate($event)"></router-outlet>

在您的组件中,您可以这样做。

onActivate(elementRef) {
    elementRef.<the @Output eventEmitter>.subscribe(event => {
        console.log(event);
    });
}

这样您就可以将事件发送到呈现router-outlet的组件。这是有效的,因为@Output事件发射器是事件流,您可以订阅这些事件。

答案 2 :(得分:0)

您不能这样做,将router-oulet视为一个组件,并且此组件没有此事件。

我认为最好的解决方案是将登录数据保存在共享服务中。