2016-06-29 4 views
3

Ich versuche, funktionale reaktive denken und eine Liste von Elementen auf einer Seite als Stream einrichten. Dies geschieht mit Angular2, aber das Problem sollte einer Stream-basierten Architektur ähneln. Also, ich habe derzeit zwei Streams, der anfängliche Stream (http-Aufruf, um eine Liste von Benutzern von Github zu erhalten) und einen Remove-Benutzer-Stream (tritt auf, wenn der Benutzer entfernen-Button geklickt wird). Ich glaube, das Marmordiagramm würde wie folgt aussehen:Kombinieren Sie den ersten Stream mit Modify-Streams mit RxJS

|[user1,user2,user3]|      <--- http initial stream 
|---------------------x----------x-----... <--- x denotes user removed 

Wie kombiniere ich diese Streams, um dies zu arbeiten? Ich denke auch später daran, mehr Streams zum Sortieren und Bestellen zu haben. Gehe ich das richtig? Hier ist der Code (beachten Sie, dieser Code unvollständig ist, derzeit der RemoveUser $ ist nicht interaktiv mit dem Benutzer $, die ihm zukommende):

export class UserGridComponent implements OnInit { 
    public users$: Observable<any>; 
    public removeUser$: Subject; 

    constructor(private _githubUserService: GithubUserService) { } 

    ngOnInit() { 
     this.removeUser$ = new Subject() 
      .subscribe((user) => { console.log('next ' + JSON.stringify(user)}); 
     this.users$ = this._githubUserService.getUsers() 
      .map((res) => res.json()); 
    } 
} 

hier die Plunker

ist zur Zeit ich nur anmelden um zu bestätigen, dass die Schaltfläche "Entfernen" angeklickt wird und den Benutzer übergibt.

Hier ist die HTML-Vorlage, die zeigt, dass ich für den Benutzer $ abonnieren, indem Sie von der Asynchron-Rohr (Angular2) mit:

<md-list> 
    <h1 md-header>GitHub Users</h1> 
    <md-list-item *ngFor="let user of users$ | async"> 
    <a href="https://github.com/{{user.login}}" target="_new"> 
     <img md-list-avatar [src]="user.avatar_url"> 
    </a> 
    <h4>{{user.login}}</h4> 
    <button md-icon-button (click)="removeUser$.next(user)"> 
     <md-icon>cancel</md-icon> 
    </button> 
    </md-list-item> 
</md-list> 
+0

Ich bin nicht 100% klar, was Sie versuchen, in Ihrem Code zu dem 'Benutzer, die Sie nie abonnierten zu erreichen, aber $ 'beobachtbar, so ist es wahrscheinlich noch kalt. – hartz89

+0

Ich abonniere den Benutzer $ beobachtbar in der Vorlage mit angular2 async pipe. Ich versuche, den Benutzer aus dem Benutzer $ zu entfernen, wann immer ein Ereignis removeUser $ auftritt. Ich werde die Vorlage auch posten, es ist im Plunker, danke. –

Antwort

0
ngOnInit() { 
    this.users$ = new BehaviorSubject([]); // init with empty user array 
    this._githubUserService.getUsers() 
     .map((res) => res.json()) 
     .subscribe(this.users$); 

    this.removeUser$ = new Subject(); 
    this.removeUser$.subscribe((user) => { 
     this.users$.take(1) // get current users, as users$ is a BehaviorSubject 
      .map(users => users.filter(u => u != user)) // remove `user` 
      .subscribe(this.users$); // update users$ stream 
    }); 
} 

meine Kommentare Hoffnung als Erklärung dienen kann. BehaviorSubject cache zuletzt ausgegebener Wert, so dass this.users $ .take (1) synchron ist. Ich benutze ein BehaviorSubject als Quelle für angular2 '| async 'Pipe sehr oft.

EDIT: Gleiche Idee, aber etwas kürzer für den removeUser$ Teil:

..... 
    this.removeUser$.withLatestFrom(user$, 
     (toRemove, users) => users.filter(u => u != toRemove) // remove `toRemove` 
    ).subscribe(this.users$); // update users$ stream 
+0

obwohl dies funktioniert, scheint es wirklich verwirrend und nicht einfach, meinen Kopf herum zu wickeln ... Ich frage mich, ob in diesem Anwendungsfall wäre es am besten, Zustand zu halten (mit redux), so dass wir aus einem Stream entfernen können. Wo meine anderen Anwendungsfälle - Filter, Sortieren - Kombinieren der Streams wäre in Ordnung .. oder wenn es eine bessere Möglichkeit gibt, dies ohne den eingebetteten Benutzer-Stream zu schreiben –