ディレクティブによって発行されたイベントを手動でサブスクライブしたいと考えています。これは、設計上、アプリケーションの複数のコンポーネントで利用できるようになっている必要があります。現時点では、構造は次のようになります。
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 ]
})
開発の後半では、別の親コンポーネントがドラッグ可能なディレクティブをリッスンし、独自のロジックを実装します。
子コンポーネントはどれも、ドラッグ可能なディレクティブがそれに何かをしていることを認識していません (または気にする必要はありません)。親コンポーネントが必要です。したがって、親コンポーネントでは:
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 ではなく Subject を使用するディレクティブを次に示します。
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);
}
}
}
正しい値で「発行」するコンソール ログを取得します。コンソールの親コンポーネントから「リッスン」することはありません。ここで何が間違っていますか?