2017-06-15 47 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