J'essaie d'implémenter un composant de vue arborescente. Ce composant s'utilise récursivement. Je l'ai obtenu pour fonctionner correctement et afficher tous les répertoires et sous-répertoires.Observable ne fonctionne pas correctement dans les composants AngularJS2 imbriqués
Le problème auquel je suis confronté concerne les événements (élément sélectionné). Tous les composants de l'arborescence s'abonnent à l'événement de service partagé, tout comme le composant de base.
Lorsque je débogue le code, je peux voir qu'à tout moment, le service a seulement 1 écouteur à l'événement, ce qui est faux. Le composant de base ne reçoit aucun rappel, ainsi que d'autres problèmes.
En cliquant sur un répertoire, je peux voir à l'intérieur du service partagé que le nombre d'auditeurs est mal réglé à 1.
Edit: Je peux voir que le constructeur de TreeViewService est appelé 4 fois (au lieu de 1).
utilisant AngularJS 2.0.0-RC.2
Voici le code.
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
});
}
}
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>
Où fournissez-vous le 'TreeViewService'. Si vous le fournissez à 'TreeViewComponent', chaque composant aura sa propre instance. Vous devez le fournir à un parent. –
TreeViewService est fourni dans le tableau des fournisseurs du composant de base. C'est le composant racine. Il est également fourni dans le composant TreeViewComponent. – sm0ke21
Je suppose que vous devez utiliser 'share' ou' publish' https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/publish.md pour plusieurs abonnés.Je n'utilise pas moi-même les rxjs et je ne connais pas les détails. –