我试图阻止主流,直到使用withLatestFrom
运算符和辅助流(包含有关配置状态的信息)初始化配置。
这是我的代码:
@Effect()
public navigationToActiveRedemptionOffers = this.actions$.ofType(ROUTER_NAVIGATION)
.filter((action: RouterNavigationAction<RouterStateProjection>) => {
return action.payload.event.url.includes('/redemption-offers/list/active');
})
.do(() => console.log('before withLatestFrom'))
.withLatestFrom(
this.store.select(selectConfigInitialized)
.do(initialized => console.log('before config filter', initialized))
.filter(initialized => initialized)
.do(initialized => console.log('after config filter', initialized)),
)
.do(() => console.log('after withLatestFrom'))
.switchMap(data => {
const action = data[0] as RouterNavigationAction<RouterStateProjection>;
return [
new MapListingOptionsAction(action.payload.routerState.queryParams),
new LoadActiveOffersAction(),
];
});
问题是第二个do
(在withLatestFrom
之后)块永远不会被调用。
经度:
感谢您的建议。
答案 0 :(得分:2)
我认为你想要的是.combineLatest
。
withLatestFrom
只会将之前的内容视为触发器。
combineLatest
将提供给它的源和可观察对象视为触发器。
所以你的问题是源(路由更改)触发并且传递给withLatest
(状态已初始化)的observable由于其过滤器而尚未激活。它只在源触发后发出一个值。所以它被忽略了。
以下是您正在做的一个正在运行的示例:
const first = Rx.Observable.create((o) => {
setTimeout(() => {
o.next();
}, 2000);
});
const second = Rx.Observable.create((o) => {
setTimeout(() => {
o.next(false);
}, 1000);
setTimeout(() => {
o.next(true);
}, 3000);
});
first
.do(() => console.log('before withLatestFrom'))
.withLatestFrom(
second
.do(initialized => console.log('before config filter', initialized))
.filter(initialized => initialized)
.do(initialized => console.log('after config filter', initialized)),
)
.subscribe(() => console.log('after withLatestFrom'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.2/Rx.js"></script>
以下是combineLatest
:
const first = Rx.Observable.create((o) => {
setTimeout(() => {
o.next();
}, 2000);
});
const second = Rx.Observable.create((o) => {
setTimeout(() => {
o.next(false);
}, 1000);
setTimeout(() => {
o.next(true);
}, 3000);
});
first
.do(() => console.log('before withLatestFrom'))
.combineLatest(
second
.do(initialized => console.log('before config filter', initialized))
.filter(initialized => initialized)
.do(initialized => console.log('after config filter', initialized)),
)
.subscribe(() => console.log('after withLatestFrom'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.2/Rx.js"></script>
答案 1 :(得分:1)
withLatestFrom
仅在其源Observable发出时才会发出。会发生的事情是this.store.select
在源withLatestFrom
之前发出。您可以从排放顺序中看到它:
之前使用最新的
...
现在取决于你想要达到的目标。只有当源使用this.store.select(selectConfigInitialized)
:
concatMap
navigationToActiveRedemptionOffers = this.actions$.ofType(ROUTER_NAVIGATION)
.filter(...)
.concatMap(() => this.store.select(selectConfigInitialized)...)
.switchMap(data => { ... })
...
或者您可以传递两个Observables的结果:
navigationToActiveRedemptionOffers = this.actions$.ofType(ROUTER_NAVIGATION)
.filter(...)
.concatMap(nav => this.store.select(selectConfigInitialized)
.map(result => [nav, result])
)
.switchMap(data => { ... })
...
答案 2 :(得分:0)
通过反转可观察量可以使其更简单。
protected void Page_Load(object sender, EventArgs e)
{
//whatever you use declarative binding (in aspx page), or define data source here
if (!IsPostBack)
{
ddl.DataBind(); //fire databinding events and fill items, and selectedvalue has a value.
}
//you can get the selectedvalue
var sv=ddl.SelectedValue ; //
}
由于这是一种常见模式,因此我使用通用public navigationToActiveRedemptionOffers =
return this.store.select(selectConfigInitialized)
.filter(initialized => initialized)
.flatMap(x =>
return this.actions$.ofType(ROUTER_NAVIGATION)
.filter((action: RouterNavigationAction<RouterStateProjection>) => {
return action.payload.event.url.includes('/redemption-offers/list/active');
})
.map(action =>
return [
new MapListingOptionsAction(action.payload.routerState.queryParams),
new LoadActiveOffersAction(),
];
)
方法。
waitFor
用法,
export const waitFor$ = function() {
return this.filter(data => !!data ).take(1);
};
提供的流利语法
return this.config$
.waitFor$()
.flatMap(config => {
return observableWithRequiredValue()
}
注意,这种运算符创建方法已被rxjs v5.5中的Lettable Operators取代(但上述方法仍有效)。