2016-04-24 15 views
4

EventSource(サーバー送信イベント)からRxJs Observableを作成します。(サーバー送信)EventSourceからRxJS Observableを作成する

私は次のことを試してみました:

import {Component, OnInit} from 'angular2/core'; 
import {Subject, Observable} from 'rxjs/Rx'; 

@Component({ 
    selector: 'my-app', 
    template: `<h1>My second Angular 2 App</h1> 
    <ul> 
     <li *ngFor="#s of someStrings"> 
      a string: {{ s }} 
     </li> 
    </ul> 
    ` 
}) 
export class AppComponent implements OnInit { 

    someStrings:string[] = []; 

    ngOnInit() { 
     let eventSource = new EventSource('/interval-sse-observable'); 
     let observable = Observable.create(eventSource); 
     observable.subscribe({ 
      next: aString => this.someStrings.push(aString.data), 
      error: err => console.error('something wrong occurred: ' + err) 
     }); 
    } 
} 

しかし、私は次の例外を取得:ここでは、完全期すため

EXCEPTION: Error: Uncaught (in promise): EXCEPTION: TypeError: this._subscribe is not a function in [null] 
ORIGINAL EXCEPTION: TypeError: this._subscribe is not a function 
ORIGINAL STACKTRACE: 
TypeError: this._subscribe is not a function 
    at Observable.subscribe (https://cdnjs.cloudflare.com/ajax/libs/angular.js/2.0.0-beta.15/Rx.js:11210:29) 
    at AppComponent.ngOnInit (http://localhost:8080/scripts/app.component.ts!transpiled:30:28) 
    at AbstractChangeDetector.ChangeDetector_HostAppComponent_0.detectChangesInRecordsInternal (viewFactory_HostAppComponent:21:99) 
    at AbstractChangeDetector.detectChangesInRecords (https://code.angularjs.org/2.0.0-beta.15/angular2.dev.js:9689:14) 
    at AbstractChangeDetector.runDetectChanges (https://code.angularjs.org/2.0.0-beta.15/angular2.dev.js:9672:12) 
    at AbstractChangeDetector.detectChanges (https://code.angularjs.org/2.0.0-beta.15/angular2.dev.js:9661:12) 
    at ChangeDetectorRef_.detectChanges (https://code.angularjs.org/2.0.0-beta.15/angular2.dev.js:5280:16) 
    at https://code.angularjs.org/2.0.0-beta.15/angular2.dev.js:13048:27 
    at Array.forEach (native) 
    at ApplicationRef_.tick (https://code.angularjs.org/2.0.0-beta.15/angular2.dev.js:13047:34) 

は私のindex.htmlの内容は次のとおりです。

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <title>sse demo</title> 
    <!-- 1. Load libraries --> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/2.0.0-beta.15/angular2-polyfills.js"></script> 
    <script src="https://code.angularjs.org/tools/system.js"></script> 
    <script src="https://code.angularjs.org/tools/typescript.js"></script> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/2.0.0-beta.15/Rx.js"></script> 
    <script src="https://code.angularjs.org/2.0.0-beta.15/angular2.dev.js"></script> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/2.0.0-beta.15/http.dev.js"></script> 

    <!-- 2. Configure SystemJS --> 
    <script> 
     System.config({ 
      transpiler: 'typescript', 
      typescriptOptions: { emitDecoratorMetadata: true } 
     }); 
     System.import('./scripts/app.ts') 
       .then(null, console.error.bind(console)); 
    </script> 
</head> 
<body> 

<my-app>Loading...</my-app> 

</body> 
</html> 

誰かが助けてくれますか?

編集1:次のようにYurzuiのアドバイスの後、私は自分のコードを変更:

ngOnInit() { 
    let observable = Observable.create(observer => { 
     const eventSource = new EventSource('/interval-sse-observable'); 
     eventSource.onmessage = x => observer.next(console.log(x)); 
     eventSource.onerror = x => observer.error(console.log('EventSource failed')); 

     return() => { 
      eventSource.close(); 
     }; 
    }); 
    observable.subscribe({ 
     next: aString => this.someStrings.push(aString.data), 
     error: err => console.error('something wrong occurred: ' + err) 
    }); 
} 

次のようにコンソールの最初のメッセージをログに記録します:

MessageEvent {isTrusted: true, data: "c374a15b-b37d-498e-8ab0-49643b79c1bb", origin: "http://localhost:8080", lastEventId: "", source: null…}bubbles: falsecancelBubble: falsecancelable: falsecurrentTarget: EventSourcedata: "c374a15b-b37d-498e-8ab0-49643b79c1bb"defaultPrevented: falseeventPhase: 0isTrusted: trueisTrusted: truelastEventId: ""origin: "http://localhost:8080"path: Array[0]ports: nullreturnValue: truesource: nullsrcElement: EventSourcetarget: EventSourcetimeStamp: 6257.125type: "message"__proto__: MessageEvent 
Rx.js:10982 Uncaught TypeError: Cannot read property 'data' of undefinedSystem.register.exports_1.execute.AppComponent.ngOnInit.observable.subscribe.next @ app.component.ts:29SafeSubscriber.__tryOrUnsub @ Rx.js:10979SafeSubscriber.next @ Rx.js:10934Subscriber._next @ Rx.js:10894Subscriber.next @ Rx.js:10871System.register.exports_1.execute.AppComponent.ngOnInit.Rx_1.Observable.create.eventSource.onmessage @ app.component.ts:21 

代わりの場合コンソールにx変数を記録します。次のように次の方法に渡します。

eventSource.onmessage = x => observer.next(x); 

サーバー送信されたイベントは、(私はクロームのdevのツールでそれらを参照してください)、クライアントによって取得されますが、何も...私が持っていたところで

取り込まれていない文字列の配列を示すテンプレートに表示されていませんエラーの原因としてJSON.parse(x.data)を削除してください。

答えて

8

は手動のEventSourceストリームのための観測を作成するには、次のコードを使用することができます。

export class AppComponent implements OnInit { 
    someStrings:string[] = []; 

    constructor(private zone: NgZone) {} 

    ngOnInit(){ 
    const observable = Observable.create(observer => { 
     const eventSource = new EventSource('/interval-sse-observable'); 
     eventSource.onmessage = x => observer.next(x.data); 
     eventSource.onerror = x => observer.error(x); 

     return() => { 
     eventSource.close(); 
     }; 
    }); 

    this.subscription = observable.subscribe({ 
     next: guid => { 
     this.zone.run(() => this.someStrings.push(guid)); 
     }, 
     error: err => console.error('something wrong occurred: ' + err) 
    }); 
    } 
} 

// somewhere 
// this.subscription.unsubscribe() 

はNgZoneクラスをインポートすることを忘れないでください:

import {Component, OnInit, NgZone} from '@angular/core'; 

Angular2 View Not Changing After Data Is Updated

+0

感謝を参照してください@ yurzui、あなたの返事を考慮に入れて投稿を編集しました。 – balteo

+0

私の解決策を更新しました – yurzui

+0

いいえ、運がありません...私はアドバイスとして試してみましたが、どちらもうまくいきませんでした。 – balteo

関連する問題