2017-06-15 50 views
2

我正在嘗試編寫一個簡單的錯誤處理服務。它可以接收錯誤並將它們添加到數組中,但由於某種原因它不起作用。數組無法正常工作的可觀察用戶和訂閱者

errorhandling.service

@Injectable() 
export class ErrorHandlingService { 
    private errors: Array<ErrorMessage>; 

    constructor() { 
     this.errors = new Array<ErrorMessage>(); 
    } 

    getErrors(): Observable<Array<ErrorMessage>>{ 
     return Observable.of(this.errors); 
    } 

    handleError(error: Response, errorText: string) { 
     let errorMessage = this.createErrorMessage(error); 
     errorMessage.displayText = errorText; 
     this.errors.push(errorMessage); 
    } 

    private createErrorMessage(error: Response): ErrorMessage { 
     let errorMessage: ErrorMessage = new ErrorMessage(); 
     errorMessage.errorType = error.type; 
     errorMessage.statusCode = error.status; 
     return errorMessage; 
    } 
} 

export class ErrorMessage { 
    statusCode: number; 
    displayText: string; 
    errorType: ResponseType; 
} 

app.component.ts

export class AppComponent implements OnInit{ 
    errorMessage: Message[] = []; 
    constructor(private authService: AuthService, private renderer: Renderer, private errorhandlingService: ErrorHandlingService) { 
     localStorage.removeItem(AppConstants.authenticationLocalStorageKey); 
    } 

    ngOnInit(): void { 
     this.errorhandlingService.getErrors().subscribe(errorMessages =>{ 
      let errorMessage: ErrorMessage = errorMessages.pop(); 
      console.log(errorMessage); 
      this.errorMessage = errorMessage ? [{ severity: 'error', summary: '', detail: errorMessage.displayText }] : []; 
     }); 
    } 

    onDeactivate() { 
     //scroll to top of page after routing 
     this.renderer.setElementProperty(document.body, "scrollTop", 0); 
    } 
} 

app.component.html

<div class="row"> 
     <div class="col-md-1"></div> 
     <div class="col-md-10 well center-text"> 
      <p-messages [value]="errorMessage"></p-messages> 
      <router-outlet (deactivate)="onDeactivate()"></router-outlet> 
     </div> 
     <div class="col-md-1"></div> 
    </div> 

以下代碼位於另一個觸發錯誤處理服務方法的組件中。

businessArea.component.ts

this.businessAreaService.getBusinessAreaById(id) 
        .subscribe(businessArea => { 
         this.model = businessArea; 
        }, 
        error => this.errorHandlingService.handleError(error, 'Could not load Business Area')); 

編輯:我試過很多東西像Observable.from但它沒有正常工作。我不確定什麼是主題以及如何使用它,但似乎Observable在我的場景中是有意義的。任何有用的鏈接也會有所幫助?我可以斷點,我可以看到它擊中了方法,並推入數組中的錯誤,但訂閱app.component永遠不會被調用。

預期的行爲:this.businessAreaService.getBusinessAreaById被稱爲在一個錯誤的情況下它調用其errorHandlingService.handleError通過調用方法this.errorHandlingService.handleError記錄錯誤在errorHandlingService陣列。現在我有一個訂戶app.component這應該在數組中添加一個錯誤時調用,以便我可以在div中顯示錯誤。

什麼不工作: 當一個元素/錯誤被添加到錯誤處理服務中的數組時,app.component.ts上的訂閱者不會被調用。不應該添加數組中的元素觸發用戶?它只在調用ngOnit時第一次被調用。在任何後續的錯誤訂閱者不被調用之後。雖然我可以看到錯誤正在推入陣列。

+0

能否請您詳細說明是不是有什麼功能工作和你期待它做什麼? – Raven

+0

@Raven我編輯了我的問題,我不確定我還能寫什麼來解釋更好。你認爲我的編輯有意義嗎? –

+0

是的一切工作正常。當我運行應用程序時,我在console.log中得到了未定義,因爲沒有錯誤,但在隨後的調用中,它不記錄任何內容。它的用戶不會被稱爲第二次以上時間 –

回答

0

您可以使用Subject來實現它,更新代碼的服務類中像下面,你沒有修改任何東西除了服務類

import { Subject } from 'rxjs'; 

@Injectable() 
export class ErrorHandlingService { 
    private errors: Array<ErrorMessage>; 
    private broadcaster = new Subject<Array<ErrorMessage>>(); 

    constructor() { 
     this.errors = new Array<ErrorMessage>(); 
    } 

    getErrors(): Subject<Array<ErrorMessage>>{ 
     return this.broadcaster; 
    } 

    handleError(error: Response, errorText: string) { 
     let errorMessage = this.createErrorMessage(error); 
     errorMessage.displayText = errorText; 
     this.errors.push(errorMessage); 
     // letting all subscribers know of the new change 
     this.broadcaster.next(this.errors); 
    } 

    private createErrorMessage(error: Response): ErrorMessage { 
     let errorMessage: ErrorMessage = new ErrorMessage(); 
     errorMessage.errorType = error.type; 
     errorMessage.statusCode = error.status; 
     return errorMessage; 
    } 
} 

export class ErrorMessage { 
    statusCode: number; 
    displayText: string; 
    errorType: ResponseType; 
} 
+0

肯定會嘗試,主體和可觀察之間有什麼區別?對不起,我是新來的這些概念 –

+0

啊..我剛從手機切換到桌面發佈這個答案。請使用'@ reactivex/rxjs/es6/Subject.js''中的正確導入'import {Subject}來避免任何樹狀結構的問題。 – Raven

+0

'Subject'與'Observable' *類似*表示'Subject'允許你訂閱它來監聽更新,然而'Subject's不會向那些運算符提供'Observable's,並且您必須手動調用'Subject'上的'next'來將更改推送到訂戶 – Dummy