Observable在嵌套的AngularJS2组件中无法正常工作

时间:2016-07-20 10:00:51

标签: service angular nested components shared

我正在尝试实现树视图组件。该组件以递归方式使用自身。我已经让它正常工作并显示所有目录和子目录。

我面临的问题是处理事件(选择项目)。所有树视图组件都订阅共享服务事件,基本组件也是如此。

当我调试代码时,我可以看到,在任何给定时间,服务只有1个事件监听器,这是错误的。 这会导致基本组件无法接收任何回调,以及其他一些问题。

单击目录时,我可以在共享服务中看到侦听器的数量被错误地设置为1。

编辑:我可以看到TreeViewService的构造函数被调用了4次(而不是1次)。

使用AngularJS 2.0.0-rc.2

这是代码。

TreeViewComponent

export class TreeViewComponent {
  @Input('items') items: TreeViewItem[] = [];
  @Input('item') item: TreeViewItem = new TreeViewItem();

  constructor(private treeViewService: TreeViewService) {
    let me = this;
    this.treeViewService.on('itemSelected', function(item) {
      me.item = item;
    });
  }

  treeViewItemSelected(item: TreeViewItem) {
    this.treeViewService.broadcast('itemSelected', item);
  }

treeview.component.html



<ul class="treeview">
  <li *ngFor="let selItem of items">
    <a [class.file]="selItem.children.length == 0" [class.folder]="selItem.children.length > 0" [class.selected]="selItem.id == item.id" (click)="treeViewItemSelected(selItem)">{{selItem.title}}</a>
    <my-treeview [items]="selItem.children" *ngIf="selItem.children.length > 0"></my-treeview>
  </li>
</ul>
&#13;
&#13;
&#13;

TreeViewService

import {Injectable} from '@angular/core';
import * as Rx from 'rxjs/Rx';

@Injectable()
export class TreeViewService {

  private listeners:any;
  private eventSubject: any;
  private events: any;

  constructor(){
    this.listeners = {};
    this.eventSubject = new Rx.Subject();
    this.events = Rx.Observable.from(this.eventSubject);

    this.events.subscribe(
      ({name, args}) => {
        if(this.listeners[name]) {
          for(let listener of this.listeners[name]) {
            listener(...args);
          }
        }
      }
    );
  }

  on(name, listener) {
    if(!this.listeners[name]) {
      this.listeners[name] = [];
    }

    this.listeners[name].push(listener);
  }

  broadcast(name, ...args) {
    this.eventSubject.next({
      name,
      args
    });
  }
}

BaseComponent

@Component({
  selector: 'my-article-form',
  template: require('./articleform.component.html'),
  styles: [require('./articleform.component.scss')],
  providers: [FileUploadService, TreeViewService],
  directives: [FileManagerComponent, TreeViewComponent]
})
.
.
.

  constructor(private fileUploadService:FileUploadService, private apiService:ApiService, private treeViewService:TreeViewService) {
    let me = this;
    this.treeViewService.on('itemSelected', function(item) {
      me.treeViewItem = item;
    });
  }

BaseComponent html

Selected: {{treeViewItem.title}}<br />
<my-treeview [items]="treeViewItems"></my-treeview>

1 个答案:

答案 0 :(得分:1)

问题是服务是为每个组件实例化一次的。这是自下而上的分层方式。

见GünterZöchbauer的回答:AngularJs 2 - multiple instance of service created

引导应用程序时需要定义服务,并且需要在需要共享同一服务实例的所有其他子组件的根组件中提供服务。