Angular2:rxjs主题在Angular2子父母组件交互
问题描述:
我想手动订阅由指令发出的事件,该指令在设计上应该可用于我的应用程序的多个组件。目前的结构是这样的: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);
}
}
}
我得到了控制台日志“发光”用正确的值。我从来没有从控制台中的父组件“收听”。我在这里做错了什么?
答
您创建的指令不是服务,因此它不会转到@Component
的providers
数组,而是使用declarations
代替。例如见https://angular.io/docs/ts/latest/guide/attribute-directives.html(你可以将其添加到NgModule
为好)
也ParentComponent
不能得到你的模板,以它的构造函数的地方使用的指令的一个实例。这就是ViewChildren
的用途。例如,请参阅:https://angular.io/docs/ts/latest/api/core/index/QueryList-class.html
因此,在ParentComponent
中,您订阅了不同于您的模板正在使用的DraggableDirective
实例。
好吧,迄今为止这么好。我是否应该在子组件上订阅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