我想手動訂閱由指令發出的事件,該指令在設計上應該可用於我的應用程序的多個組件。目前的結構是這樣的:Angular2:rxjs主題在Angular2子父母組件交互
AppComponent
Draggable.Directive (uses an attribute of a DOM element to control the behaviour)
(and then, via routing)
Parent1 Component
Child1 Component
Child2 Component
app.module看起來是這樣的:
@NgModule({
imports: [ BrowserModule, HttpModule, JsonpModule, RouterModule.forRoot(appRoutes) ],
declarations: [ AppComponent, FooComponent, BarComponent, ParentComponent, DraggableDirective ],
bootstrap: [ AppComponent ]
})
的發展後,另一父組件會聽指令拖動和實施自己的邏輯。
沒有一個子組件知道(或應該關心)Draggable指令對它做任何事情。父組件應該。所以,在父組件:
import { Component, OnInit, ViewChild } from '@angular/core';
import { DraggableDirective } from './draggable.directive';
import { FooComponent } from './foo.component';
import { BarComponent } from './bar.component';
@Component({
selector: 'parent-view',
templateUrl: './parent.component.html',
providers: [DraggableDirective],
moduleId: module.id
})
export class ParentComponent implements OnInit {
@ViewChild('foo') fooC:FooComponent;
@ViewChild('bar') barC:BarComponent;
constructor(private draggable:DraggableDirective){
draggable.droppedOn.subscribe(event => {
console.log('listening', event);
})
}
ngOnInit(): void {
// updated
// child view components
this.fooC.fooInit();
}
這裏是指令,使用主題和不EventEmitter,如其他部分建議:
import { Directive, ElementRef, Renderer, HostListener, AfterViewInit } from '@angular/core';
import {Subject} from 'rxjs/Rx';
@Directive({
selector: '[draggable], [data-draggable]'
})
export class DraggableDirective implements AfterViewInit {
public droppedOn = new Subject();
//... at some point this method is envoked
couldDrop():void {
if (this.dElem) {
let _attr = this.dElem.dataset.indexed;
console.log('emitting', _attr);
this.droppedOn.next(_attr);
}
}
}
我得到了控制檯日誌「發光」用正確的值。我從來沒有從控制檯中的父組件「收聽」。我在這裏做錯了什麼?
好吧,迄今爲止這麼好。我是否應該在子組件上訂閱Subject()並將其轉發給父組件? – pop
@pop不,你使用'@ ViewChildren'註解和'QueryList',它是父組件中的Observable本身,以獲得所有'DraggableDirective'指令的更新列表。在那裏你可以訪問每個訂閱它的'droppedOn'屬性。 – martin
請參閱http://stackoverflow.com/questions/32693061/angular-2-typescript-get-hold-of-an-element-in-the-template/35209681#35209681 – martin