Angular2:Angular2子父组件交互中的rxjs主题

时间:2016-12-06 14:41:21

标签: angular typescript rxjs rxjs5 subject-observer

我想手动订阅指令发出的事件,该指令在设计上应该可用于我的应用程序的多个组件。目前结构看起来像这样:

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 ]
})

在开发的后期,另一个Parent组件将监听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();
  }

这是指令,使用Subject而不是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);

        }

    }
}

我使用正确的值获取控制台日志记录“emit”。我永远不会从控制台中的父组件“监听”。我在这里做错了什么?

1 个答案:

答案 0 :(得分:2)

您创建的指令不是服务,因此它不会转到@Component的{​​{1}}数组,而是转移到providers。例如,请参阅https://angular.io/docs/ts/latest/guide/attribute-directives.html(您也可以将其添加到declarations

同样NgModule无法将模板中某处使用的指令实例添加到其构造函数中。这是ParentComponent的用途。例如,请参阅:https://angular.io/docs/ts/latest/api/core/index/QueryList-class.html

因此,在ViewChildren中,您订阅的ParentComponent实例与您的模板使用的不同。