我有一个关于@ngrx效果的非常基本的问题:如何忽略在执行效果期间发生的错误,使其不影响将来的效果执行?
我的情况如下:我有一个动作(LOGIN)和一个听取该动作的效果.如果在此效果中发生错误,我想忽略它.在此错误后第二次调度LOGIN时,应该再次执行该效果.
我的第一次尝试是:
@Effect()
login$ = this.actions$
.ofType('LOGIN')
.flatMap(async () => {
console.debug('LOGIN');
// throw an error
let x = [];x[0]();
})
.catch(err => {
console.error('Error at login', err);
return Observable.empty();
});
Run Code Online (Sandbox Code Playgroud)
第一次调度LOGIN会按预期方式抛出并捕获错误.但是,如果我之后第二次发送LOGIN,则没有任何反应; 效果未执行.
因此我尝试了以下方法:
.catch(err => {
return this.login$;
});
Run Code Online (Sandbox Code Playgroud)
,但这导致无限循环......你知道如何在不阻止事后执行效果的情况下捕获错误吗?
当在使用.share()运算符的observable上使用异步管道时(由于后端的昂贵计算),我偶然发现了这种行为:
data$ = (new Observable(observer => {
let counter=0;
observer.next(counter)
window.setInterval(() => {
observer.next(counter);
counter++;
}, 2000);
}))
.share();
Run Code Online (Sandbox Code Playgroud)
模板:
{{ (data$|async) !== null }}
{{ (data$|async) !== null }}
Run Code Online (Sandbox Code Playgroud)
初始值的输出是:
true false
Run Code Online (Sandbox Code Playgroud)
以下输出(超过2秒后)是:
true true
Run Code Online (Sandbox Code Playgroud)
这也是我对第一个值所期望的行为.如果省略.share(),则第一个值的输出为"true true",正如我所料.我想上面的行为是由于模板中的第一个表达式触发了可观察的执行,并且一旦第二个异步管道订阅了observable,数据就已经消失了.这个解释是否正确?我怎样才能避免这种行为?
我正在编写一个 angular 2 应用程序,出于性能原因,我尝试在任何地方使用 ChangeDetectionStrategy.OnPush。我有一个需要 OnPush 才能顺利工作的复杂组件,其中包含另一个显示表单的组件(使用 FormBuilder 创建)。我现在注意到,当我点击一个滑块时,它的内部值会更新(即 form.value),但滑块组件不会可视化这个新值,即它卡在旧位置。
我解决这个问题的第一个想法是将叶组件的更改检测策略设置为默认值,但这没有效果,因为显然这也需要更改其父组件的更改检测策略(这在我的应用程序中是不可能的)。
然后我想出了这个主意:
@Component({
...
})
class MyComponent implements OnInit {
constructor(private zone: NgZone) {}
ngOnInit() {
INIT_FORM();
this.form.valueChanges
.subscribe(() => {
this.zone.run(() => {});
});
}
}
Run Code Online (Sandbox Code Playgroud)
但它没有效果。
是否有可能使 angular 2 表单在使用 OnPush 的组件内工作?
我有一个由效果调用的昂贵计算.我现在想要确保,此计算永远不会同时调用,即如果在第一次调用仍在运行时第二次调用它,则应忽略第二次调用.
我解决这个问题的方法是创建2个动作:calculate和setLoading.
@Effect()
calculate$ = this.updates$
.whenAction(CALCULATE)
.flatMap(data => {
console.debug('LOADING', data.state.loading);
if (!data.state.loading) {
this.store.dispatch(Actions.setLoading(true));
await DO_THE_EXPENSIVE_CALCULATION();
this.store.dispatch(Actions.setLoading(false));
}
});
Run Code Online (Sandbox Code Playgroud)
使用Actions.setLoading显然设置state.loading.但是,如果我连续开始计算2次:
store.dispatch(Actions.calculate());
store.dispatch(Actions.calculate());
Run Code Online (Sandbox Code Playgroud)
输出是
LOADING false
LOADING false
Run Code Online (Sandbox Code Playgroud)
因此,昂贵的计算执行两次.我怎么能阻止这个?