【发布时间】:2017-04-09 12:08:08
【问题描述】:
我正在尝试使用具有更多可重用组件的 angular2 构建一个小型应用程序。在这里,我想要一个 Loader Service,它会在每次 xhr 调用时执行。
为此,这就是我想出的
-
使用承诺
export class SpinnerService { showSpinner = false; spinnerPromise(observableToWaitFor: Observable<any>, text?: string): Promise<any> { this.showSpinner = true; return promiseToWaitFor.toPromise() .then((data) => { this.showSpinner = false; return data; }); } }这就是我使用 SpinnerService 的方式
constructor(private requestService: RequestService, private spinnerService: SpinnerService) { } signin(username: string, password: string) { let url = _.template(API_Constant.LOGIN)({ username: username }); return this.spinnerService.spinnerPromise(this.requestService .makeRequest(url, RequestMethod.Get)) .then(data => { let peoples = data.results; let found = _.find(peoples, (p: any) => p.name.toLowerCase() === username.toLowerCase()); if (found && found.birth_year === password) { } else { return Promise.reject('Invalid username or password'); } }); } }它在某种程度上可以正常工作。但我不太相信这种用法,因为它限制 AuthService 使用 Promise。
-
使用 Observable
我是使用 Observable 的初学者,所以我不知道实现一个通用的 Loader Service 是多么困难或容易。
这是我尝试过的
@Injectable()
export class SpinnerService {
showSpinner = false;
public consumer: ReplaySubject<any> = new ReplaySubject(1);
spinnerPromise(observableToWaitFor: Observable<any>, text?: string) {
this.showSpinner = true;
return observableToWaitFor.subscribe(
response => this.consumer.next(response),
error => { this.showSpinner = false; },
() => { this.showSpinner = false; }
);
}
}
这会返回一个订阅。但是有没有办法在不订阅的情况下更新 showSpinner。
【问题讨论】:
-
您可以使用
.do()来执行副作用,但这假设您以后无论如何都会订阅 Observable。 -
@martin 如果 api 调用失败,.do() 还会被执行吗?
-
do()需要三个回调。对于next、error和complete信号,您可以选择要处理的内容。 -
您可以将其创建为自定义公共组件,而不是将其创建为服务,如answer
-
@Aravind 我已经有一个组件 SpinnerComponent 与显示/隐藏加载器的 SpinnerService 交互。
标签: angular typescript rxjs