Observable 在嵌套的 AngularJS2 组件中无法正常工作
Observable not working correctly in nested AngularJS2 components
我正在尝试实现树视图组件。该组件递归地使用自身。我已经让它正常工作并显示所有目录和子目录。
我面临的问题是在处理事件时(已选择项目)。所有树视图组件都订阅共享服务事件,基本组件也是如此。
当我调试代码时,我可以看到在任何给定时间,该服务只有 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>
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
});
}
}
基础组件
@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;
});
}
基础组件html
Selected: {{treeViewItem.title}}<br />
<my-treeview [items]="treeViewItems"></my-treeview>
问题是服务为每个组件实例化一次。这以自下而上的分层方式工作。
在此处查看 Günter Zöchbauer 的回答:AngularJs 2 - multiple instance of service created
在引导应用程序时需要定义服务,并且仅在需要共享同一服务实例的所有其他子组件的根组件中提供。
我正在尝试实现树视图组件。该组件递归地使用自身。我已经让它正常工作并显示所有目录和子目录。
我面临的问题是在处理事件时(已选择项目)。所有树视图组件都订阅共享服务事件,基本组件也是如此。
当我调试代码时,我可以看到在任何给定时间,该服务只有 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>
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
});
}
}
基础组件
@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;
});
}
基础组件html
Selected: {{treeViewItem.title}}<br />
<my-treeview [items]="treeViewItems"></my-treeview>
问题是服务为每个组件实例化一次。这以自下而上的分层方式工作。
在此处查看 Günter Zöchbauer 的回答:AngularJs 2 - multiple instance of service created
在引导应用程序时需要定义服务,并且仅在需要共享同一服务实例的所有其他子组件的根组件中提供。