2017-05-23 25 views
0

私のビューはサービスから更新されないという問題で苦労しています。角度4ビューまたはサービスから更新しました

私が達成しようとしているのはメッセージ処理です。私はサービスにメッセージを送り、購読されたコンポーネントは更新されます。モデルでは、すべてが完璧に動作しますが、ビューはまったく変化しません。

マイサービス:

import {Injectable} from '@angular/core'; 
import {Observer} from 'rxjs/Observer'; 
import {Subscription} from 'rxjs/Subscription'; 
import {Subject} from 'rxjs/Rx'; 

import {MyMessage} from './myMessage'; 

@Injectable() 
export class MessageHandlingService { 
    private _message: Subject<MyMessage> = new Subject(); 

    handle(message: string, stack: string) { 
     // console.log('handle', message, stack); 
     let newMyMessage: MyMessage; 

     if (stack) { 
      newMyMessage = new MyMessage(2, message, stack); 
     } else { 
      newMyMessage = new MyMessage(1, message, stack); 
     } 

     this._message.next(newMyMessage); 
    } 

    subscribeMessages(observer: Observer<MyMessage>): Subscription { 
     // console.log('MessageHandling - subscriber accepted'); 
     return this._message.subscribe(observer); 
    } 
} 

マイコンポーネント:

import {Component, OnInit, OnDestroy} from '@angular/core'; 
import {Observer} from 'rxjs/Observer'; 
import {Subscription} from 'rxjs/Subscription'; 

import {MessageHandlingService} from './messageHandling.service'; 
import {MyMessage} from './myMessage'; 

@Component({ 
    templateUrl: './my-messager.component.html', 
    selector: 'mymy-messager' 
}) 
export class MyMessagerComponent implements OnInit, OnDestroy, Observer<MyMessage> { 

    private _subscription: Subscription; 

    display: boolean = false; 

    msg: MyMessage = null; 

    constructor(private messageHandling: MessageHandlingService) {} 

    ngOnInit() { 
     console.log('MyMessager is subscribing'); 
     this._subscription = this.messageHandling.subscribeMessages(this); 
    } 

    ngOnDestroy() { 
     console.log('MyMessager is UN-subscribing'); 
     if (this._subscription) { 
      this._subscription.unsubscribe(); 
     } 
    } 

    /* istanbul ignore next */ 
    complete() {} 

    /* istanbul ignore next */ 
    error(e: any) { 
     if (console) { 
      console.error(e); 
     } 
    } 

    next(message: MyMessage) { 
     console.log('observed next', message); 
     this._showMessage(message); 
    } 

    private _showMessage(message: MyMessage) { 
     this.msg = message; 
     console.log('Settind display to true') 
     this.display = true; 
    } 

    hideDialog() { 
     this.msg = null; 
     this.display = false; 
    } 
} 

とコンポーネントHTML私が試してみました

{{msg}} 
{{display}} 
<span *ngIf="msg"> 
    <span *ngIf="msg.severity === 1"> 
     <p-dialog 
      header="Information message" 
      [(visible)]="display" 
      modal="modal" 
      showEffect="fade"> 
      <p>{{msg.message}}</p> 
      <footer> 
       <div 
        class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"> 
        <button type="button" pButton icon="fa-close" (click)="hideDialog()" label="OK"></button> 
       </div> 
      </footer> 
     </p-dialog> 
    </span> 
    <span *ngIf="msg.severity === 2"> 
     <p-dialog 
      header="Technical message" 
      [(visible)]="display" 
      modal="modal" 
      showEffect="fade"> 
      <p>{{msg.message}}</p> 
      <br /> 
      <hr /> 
      <p style="white-space: pre;">{{msg.stackTrace}}</p> 
      <footer> 
       <div 
        class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"> 
        <button type="button" pButton icon="fa-close" (click)="hideDialog()" label="OK"></button> 
       </div> 
      </footer> 
     </p-dialog> 
    </span> 
</span> 

ChangeDetectorRef.detectChanges() 

ChangeDetectorRef.markForCheck() 

ApplicationRef.tick() 

とさえ

NgZone run 

が、運。同じコードが角度2で機能しました。

+0

のようなオブジェクトを使用できますか? –

答えて

2

this._message.subscribe(observer);実行中にSafeSubscriberが

function SafeSubscriber(_parentSubscriber, observerOrNext, error, complete) { 
    _super.call(this); 
    this._parentSubscriber = _parentSubscriber; 
    var next; 
    var context = this; 
    if (isFunction_1.isFunction(observerOrNext)) { 
     next = observerOrNext; 
    } 
    else if (observerOrNext) { 
     next = observerOrNext.next; 
     error = observerOrNext.error; 
     complete = observerOrNext.complete; 
     if (observerOrNext !== Observer_1.empty) { 
      context = Object.create(observerOrNext); // this line 

だからあなたが例えば

enter image description here

enter image description here

現在AppComponentインスタンスへのリンクを失っ作成されている、これはあなたのために働く必要があります

subscribeMessages(observer: Observer<MyMessage>): Subscription { 
    const subscriber = new Subscriber(
     observer.next.bind(observer), 
     observer.error.bind(observer), 
     observer.complete.bind(observer)) 

    return this._message.subscribe(subscriber); 
} 

か、あなたはどのようなコードから更新されますことを期待しない結合どう

const subscriber = { 
    next: observer.next.bind(observer), 
    error: observer.error.bind(observer), 
    complete: observer.complete.bind(observer)) 
} 

Plunker Example

1

これはthisバインディングの問題です。あなたは

this.messageHandling.subscribeMessages({ 
     next: (message) => this.next(message), 
     error: (error) => this.complete(error), 
     complete:() => this.complete() 
    }); 

によって

this.messageHandling.subscribeMessages(this); 

を交換する場合は、あなたのコードは正常に動作しますa demoを参照してください。

あなたのサービスでObserverを引数として受け取るメソッドを公開する代わりに、Observerを引数として公開する代わりに、Observerをむしろ公開することになりました。こうすることで、呼び出し元は実際にオブザーバブルに登録する前に、必要な演算子を簡単に追加できます。 Demo

関連する問題