Преобразуйте обычную строку[] в Observable‹string[]› и объедините ее с другой Observable‹string[]› с помощью RxJS 5

Я пытаюсь преобразовать обычный string[] в Observable<string[]> и объединить его с существующим Observable<string[]>.

Затем я буду использовать канал angular2 async для отображения файла Observable.

Вот мой код:

import {Injectable} from "angular2/core";
import {Observable} from "rxjs/Observable";
import 'rxjs/Rx';


@Injectable()
export class AppService {

    constructor() {
        console.log('constructor', 'appService');
        this.constructSomeObservable();
    }

    someObservable$:Observable <string[]>;

    constructSomeObservable() {
        this.someObservable$ = Observable.create(observer => {
            const eventSource = new EventSource('/interval-sse-observable');
            eventSource.onmessage = x => observer.next(JSON.parse(x.data));
            eventSource.onerror = x => observer.error(console.log('EventSource failed'));
            return () => {
                eventSource.close();
            };
        });

        this.someObservable$.subscribe(
            theStrings=> {
                console.log(theStrings);
                //Somehow convert the plain array of strings to an observable and concat it to this.someObservable$ observable...
            },
            error=>console.log(error)
        );
    }
}

Кто-нибудь может помочь?

Кроме того, я хочу убедиться, что экземпляр службы Observable<string[]> постоянно обновляется по мере многократного вызова EventSource. Находится ли моя логика подписки в правильном месте?

редактировать 1: я пытался использовать оператор RxJS concat следующим образом:

    this.someObservable$.subscribe(
        theStrings=> {
            console.log(theStrings);
            this.someObservable$ = this.someObservable$.concat(Observable.create(theStrings));
        },
        error=>console.log(error)
    );
 }

вместе с трубой angular2 async:

<ul>
    <li *ngFor="#s of appService.someObservable$ | async">
       a string: {{ s }}
    </li>
</ul>

и ничего не отображается на странице; строки просто отображаются на консоли...

Что я делаю неправильно?

изменить 2: приложение доступно на github здесь

редактировать 3: я учел совет Тьерри, особенно использование канала async для подписки, а также использование оператора сканирования.

Единственная оставшаяся проблема заключается в том, что мне нужно щелкнуть ссылку маршрутизатора, чтобы строки отображались в шаблоне... Шаблон не обновляется автоматически...

См. проект на github и соответствующий тег: https://github.com/balteo/demo-angular2-rxjs/tree/36864628/536299


person balteo    schedule 26.04.2016    source источник


Ответы (1)


Я бы использовал для этого оператор scan. Вот пример:

@Component({
  selector: 'app'
  template: `
    <div>
      <div *ngFor="#elt of someObservable$  | async">{{elt.name}</div>
    </div>
  `
})
export class App {
  constructor() {
    this.someObservable$ = Observable.create((observer) => {
      const eventSource = new EventSource('/interval-sse-observable');
      eventSource.onmessage = x => observer.next(JSON.parse(x.data));
      eventSource.onerror = x => observer.error(console.log('EventSource failed'));
      return () => {
        eventSource.close();
      };
    })
    .startWith([])
    .scan((acc,value) => acc.concat(value));
  }
}

Вот соответствующий планкр: https://plnkr.co/edit/St7LozX3bnOBcoHaG4uM?p=preview< /а>.

См. этот вопрос для более подробной информации:

person Thierry Templier    schedule 26.04.2016
comment
Спасибо, Тьерри! Что касается асинхронного канала и статьи, которую вы предложили, у меня есть Observable<string[]>, так что все должно быть в порядке. Теперь, что касается остального кода и вашего плунжера, я удивлен, что мне не нужно подписываться. Как так? - person balteo; 26.04.2016
comment
Пожалуйста! На самом деле труба async прозрачно подписывается (и отписывается) за вас ;-) - person Thierry Templier; 26.04.2016
comment
Да, на самом деле не так очевидно ;-) См. github.com/angular/angular/blob/master/modules/angular2/src/ - person Thierry Templier; 26.04.2016
comment
Я обновил свой пост. У меня осталась одна проблема (связанная с роутером), которую я не могу воспроизвести в вашем плункере. - person balteo; 26.04.2016
comment
Думаю, я открою другой пост, так как это не та же проблема. Пометка как принятая. - person balteo; 26.04.2016
comment
Хорошо. Да, не стесняйтесь ;-) - person Thierry Templier; 26.04.2016