委托:在Angular2中的EventEmitter或Observable
我试图在Angular2中实现像一个委托模式。
当用户点击导航项时,我想调用一个函数,然后发出一个事件,该事件应该由侦听事件的其他组件处理。 这里是场景:我有一个导航组件: import {Component,Output,EventEmitter} from 'angular2/core'; @Component({ // other properties left out for brevity events : ['navchange'],template:` <div class="nav-item" (click)="selectedNavItem(1)"></div> ` }) export class Navigation { @Output() navchange: EventEmitter<number> = new EventEmitter(); selectedNavItem(item: number) { console.log('selected nav item ' + item); this.navchange.emit(item) } } 这里是观察组件: export class ObservingComponent { // How do I observe the event ? // <----------Observe/Register Event ?--------> public selectedNavItem(item: number) { console.log('item index changed!'); } } 关键问题是,如何使观察组件观察到有问题的事件?
更新2016-06-27:而不是使用Observables,使用
>一个BehaviorSubject,由@Abdulrahman在注释中推荐,或 A Subject既是一个Observable(因此我们可以订阅它)和一个Observer(所以我们可以调用next()来发出一个新的值)。我们利用这个功能。主题允许值被多播到多个观察者。我们不利用这个特性(我们只有一个Observer)。 BehaviorSubject是主题的变种。它有“当前价值”的概念。我们利用这一点:每当我们创建一个ObservingComponent,它自动从BehaviorSubject获取当前导航项值。 下面的代码和plunker使用BehaviorSubject。 ReplaySubject是主体的另一个变体。如果要等到实际生成值,请使用ReplaySubject(1)。而BehaviorSubject需要一个初始值(将立即提供),而ReplaySubject则不需要。 ReplaySubject将始终提供最近的值,但由于它没有必需的初始值,所以服务可以在返回其第一个值之前执行一些异步操作。它仍将立即触发具有最近值的后续呼叫。如果你只想要一个值,在订阅上使用first()。如果您使用first(),您不必取消订阅。 import {Injectable} from '@angular/core' import {BehaviorSubject} from 'rxjs/BehaviorSubject'; @Injectable() export class NavService { // Observable navItem source private _navItemSource = new BehaviorSubject<number>(0); // Observable navItem stream navItem$ = this._navItemSource.asObservable(); // service command changeNav(number) { this._navItemSource.next(number); } } import {Component} from '@angular/core'; import {NavService} from './nav.service'; import {Subscription} from 'rxjs/Subscription'; @Component({ selector: 'obs-comp',template: `obs component,item: {{item}}` }) export class ObservingComponent { item: number; subscription:Subscription; constructor(private _navService:NavService) {} ngOnInit() { this.subscription = this._navService.navItem$ .subscribe(item => this.item = item) } ngOnDestroy() { // prevent memory leak when component is destroyed this.subscription.unsubscribe(); } } @Component({ selector: 'my-nav',template:` <div class="nav-item" (click)="selectedNavItem(1)">nav 1 (click me)</div> <div class="nav-item" (click)="selectedNavItem(2)">nav 2 (click me)</div>` }) export class Navigation { item = 1; constructor(private _navService:NavService) {} selectedNavItem(item: number) { console.log('selected nav item ' + item); this._navService.changeNav(item); } } Plunker 原始答案使用一个Observable:(它需要更多的代码和逻辑比使用BehaviorSubject,所以我不推荐它,但它可能是有启发性的) 因此,这里是一个使用Observable instead of an EventEmitter的实现。与我的EventEmitter实现不同,此实现还将当前选择的navItem存储在服务中,以便在创建观察组件时,它可以通过API调用navItem()检索当前值,然后通过navChange $ Observable通知更改。 import {Observable} from 'rxjs/Observable'; import 'rxjs/add/operator/share'; import {Observer} from 'rxjs/Observer'; export class NavService { private _navItem = 0; navChange$: Observable<number>; private _observer: Observer; constructor() { this.navChange$ = new Observable(observer => this._observer = observer).share(); // share() allows multiple subscribers } changeNav(number) { this._navItem = number; this._observer.next(number); } navItem() { return this._navItem; } } @Component({ selector: 'obs-comp',item: {{item}}` }) export class ObservingComponent { item: number; subscription: any; constructor(private _navService:NavService) {} ngOnInit() { this.item = this._navService.navItem(); this.subscription = this._navService.navChange$.subscribe( item => this.selectedNavItem(item)); } selectedNavItem(item: number) { this.item = item; } ngOnDestroy() { this.subscription.unsubscribe(); } } @Component({ selector: 'my-nav',template:` <div class="nav-item" (click)="selectedNavItem(1)">nav 1 (click me)</div> <div class="nav-item" (click)="selectedNavItem(2)">nav 2 (click me)</div> `,}) export class Navigation { item:number; constructor(private _navService:NavService) {} selectedNavItem(item: number) { console.log('selected nav item ' + item); this._navService.changeNav(item); } } Plunker 另见Component Interaction Cookbook example,除了观察者之外,它还使用主语。尽管示例是“父和子通信”,但是相同的技术适用于不相关的组件。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 角度抽象控件删除错误
- routing – AngularJS location.path()简要更改URL,然后恢复
- angularjs – 让Jackson将Java 8 Instant序列化为纪元毫秒的
- scala – 将StringType列添加到现有Spark DataFrame,然后应
- 如何自动创建批处理/ shell脚本以运行Java控制台应用程序?
- angularjs初识
- 请求WebService出现"因 URL 意外地以 结束,请求格式无法
- shell – FreeBSD pkg_create怎么样
- 使用bash进程替换拒绝文件描述符权限?
- Docker容器中推荐的GCE服务帐户身份验证?