将普通字符串[]转换为Observable <string []>,并使用RxJS 5将其连接到另一个Observable <string []>

时间:2016-04-26 11:15:40

标签: angular rxjs5

我正在尝试将普通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)
        );
    }
}

有人可以帮忙吗?

此外,我想确保在重复调用EventSource时不断更新服务实例Observable<string[]>。我的订阅逻辑是否在正确的位置?

编辑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上使用here

编辑3 :我已经考虑了Thierry的建议,特别是使用async管道进行订阅以及使用扫描操作符。

现在唯一剩下的问题是我需要点击路由器链接才能在模板上呈现字符串......模板不会自动更新...

请参阅github和相关标签上的项目:https://github.com/balteo/demo-angular2-rxjs/tree/36864628/536299

1 个答案:

答案 0 :(得分:4)

我会利用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));
  }
}

这是相应的plunkr:https://plnkr.co/edit/St7LozX3bnOBcoHaG4uM?p=preview

有关详细信息,请参阅此问题: