为什么数组的Observable和订阅者无法正常工作?

时间:2017-06-15 16:46:03

标签: javascript angularjs arrays typescript observable

我正在尝试编写一个简单的错误处理服务。它可以接收错误并将它们添加到数组中但由于某种原因,它无法正常工作。

  

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这样的东西,但它没有用。我不确定主题是什么以及如何使用它但似乎Observable在我的场景中是有意义的。任何有用的链接也会有帮助吗?我可以断点,我可以看到它击中方法,然后它推送数组中的错误,但从未调用app.component订阅。

预期行为 在错误情况下调用this.businessAreaService.getBusinessAreaById时,它会调用errorHandlingService.handleError,通过调用方法this.errorHandlingService.handleError将错误记录在errorHandlingService的数组中。现在我在 app.component 中有一个订阅者,当一个错误被添加到数组时应该被调用,这样我就可以在div中显示错误。

什么不行: 在错误处理服务中将元素/错误添加到数组时,不会调用app.component.ts上的订阅者。不应该在数组触发器用户中添加元素?它仅在第一次调用ngOnit时调用。在任何后续错误之后,不会调用订户。虽然我可以看到错误被推送到数组中。

1 个答案:

答案 0 :(得分: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;
}