我一直试图找出一种方法来使用select运算符与rxjs的其他运算符一起查询树数据结构(在存储中规范化为平面列表),以便保留ChangeDetectionStrategy.OnPush的引用完整性语义,但我最好的尝试导致整个树在树的任何部分发生变化时被重新渲染.有没有人有任何想法?如果您将以下界面视为商店中数据的代表:
export interface TreeNodeState {
id: string;
text: string;
children: string[] // the ids of the child nodes
}
export interface ApplicationState {
nodes: TreeNodeState[]
}Run Code Online (Sandbox Code Playgroud)
我需要创建一个选择器,对上面的状态进行非规范化,以返回实现以下接口的对象图:
export interface TreeNode {
id: string;
text: string;
children: TreeNode[]
}Run Code Online (Sandbox Code Playgroud)
理想情况下,我想让图中的任何一部分只更新它的子项,如果它们已经改变而不是在任何节点改变时返回一个全新的图形.有谁知道如何使用ngrx/store和rxjs构建这样的选择器?
有关我尝试过的各种事情的更具体的例子,请查看下面的代码段:
// This is the implementation I'm currently using.
// It works but causes the entire tree to be rerendered
// when any part of the tree changes.
export function getSearchResults(searchText: string = '') { …Run Code Online (Sandbox Code Playgroud)我想在一个效果中发送两个动作.目前我必须声明两个效果来实现这一目标:
// first effect
@Effect() action1$ = this.actions$
.ofType(CoreActionTypes.MY_ACTION)
.map(res => {
return { type: "ACTION_ONE"}
})
.catch(() => Observable.of({
type: CoreActionTypes.MY_ACTION_FAILED
}));
// second effect
@Effect() action2$ = this.actions$
.ofType(CoreActionTypes.MY_ACTION)
.map(res => {
return { type: "ACTION_TWO"}
})
.catch(() => Observable.of({
type: CoreActionTypes.MY_ACTION_FAILED
}));
Run Code Online (Sandbox Code Playgroud)
是否可以通过单一效果成为一个动作的源头?
我是Redux的新手,从ngrx开始.我无法理解这行代码的含义store.select:
clock: Observable<Date>;
this.clock = store.select('clock');
Run Code Online (Sandbox Code Playgroud) 我正在将@ ngrx/effects从1.x 更新为2.x.
在1.x中,我可以访问状态树:
constructor(private updates$: StateUpdates<AppState>) {}
@Effect() bar$ = this.updates$
.whenAction(Actions.FOO)
.map(obj => obj.state.user.isCool)
.distinctUntilChanged()
.filter(x => x)
.map(() => ({ type: Actions.BAR }));
Run Code Online (Sandbox Code Playgroud)
现在在2.x中,它只给了我动作.还有办法访问状态树吗?或者我应该避免这样使用,因为这不是一个好习惯吗?
constructor(private actions$: Actions) {}
@Effect() bar$ = this.actions$
.ofType(ActionTypes.FOO)
.map((obj: any) => {
console.log(obj); // here is action only
return obj.state.user.isCool // so it is wrong here
})
.distinctUntilChanged()
.filter(x => x)
.map(() => ({ type: ActionTypes.BAR }));
Run Code Online (Sandbox Code Playgroud) 我有一个关于@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)
,但这导致无限循环......你知道如何在不阻止事后执行效果的情况下捕获错误吗?
我正在尝试做一些简单的事情 - 在一些实体保存后(使用http请求)我想导航回列表路由.问题是:如何订阅成功动作(或者可能是减速器或效果?)
这是我的行为代码:
static SAVE_POST = '[POST] Save POST';
savePOST(Post): Action {
return {
type: PostActions.SAVE_POST,
payload: Post
};
}
static SAVE_POST_SUCCESS = '[POST] Save POST Success';
savePOSTSuccess(Post): Action {
console.log('action: savePostSuccess')
return {
type: PostActions.SAVE_POST_SUCCESS,
payload:Post
};
}
Run Code Online (Sandbox Code Playgroud)
我正在使用效果:
@Effect() savePost$ = this.update$
.ofType(PostActions.SAVE_POST)
.map(action => action.payload)
.switchMap(post => this.svc.savePost(post))
.map(post => this.postActions.savePOSTSuccess(post));
Run Code Online (Sandbox Code Playgroud)
减速器:
const initialState: PostListState = [];
export default function (state = initialState, action: Action): PostListState {
switch (action.type) {
case PostActions.LOAD_POST_SUCCESS: {
return action.payload;
} …Run Code Online (Sandbox Code Playgroud) 我正在使用Angular 2和ngrx/store.我想在用户调度时重置整个商店状态USER_LOGOUT.
我读了Dan Abramov关于如何重置Redux商店状态的答案?,但我没有弄清楚如何rootReducer正确编写以及在使用ngrx/store时将其放在何处.
或者还有其他方法可以在ngrx/store中处理这个问题吗?
bootstrap(App, [
provideStore(
compose(
storeFreeze,
storeLogger(),
combineReducers
)({
router: routerReducer,
foo: fooReducer,
bar: barReducer
})
)
]);
Run Code Online (Sandbox Code Playgroud) 不推荐使用以下ngrx选择.
this.store.select(state => state.academy.academy).subscribe((academy) => {
this.academy = academy;
});
Run Code Online (Sandbox Code Playgroud)
我在store.d.ts找到了这个
@deprecated from 6.1.0. Use the pipeable `select` operator instead.
Run Code Online (Sandbox Code Playgroud)
那么......正确的语法是什么?
我试试
this.store.pipe(select(state => state.academy.academy).subscribe((academy) => {
this.academy = academy;
}))
Run Code Online (Sandbox Code Playgroud)
错误:找不到名称'select'.你是说'onselect'吗?
导入NGRX devtools使一个调试器用于铬工具结果的错误如下所示:
错误TypeError:无法读取isFiltered(:1:5016)的isFiltered(:1:5016)的未定义属性'whitelist',位于ScanSubscriber.StoreDevtools的DevtoolsExtension.notify(store-devtools.js:210)的Object.x [as send](:1:74196)位于ScanSubscriber._next(scan.js:61)的ScanSubscriber. (Subscriber.js:54)位于Notification.observe的WithLatestFromSubscriber.Subscriber.next(Subscriber.js:54)的WithLatestFromSubscriber._next(withLatestFrom.js:66)(Notification.js:15)
这是我在ngrx下面的版本:
"@ngrx/core": "^1.2.0",
"@ngrx/effects": "^6.1.2",
"@ngrx/store": "^6.1.2",
"@ngrx/store-devtools": "^6.1.2",
Run Code Online (Sandbox Code Playgroud)
和我的角度和离子
"@angular/animations": "5.2.11",
"@angular/common": "5.2.11",
"@angular/compiler": "5.2.11",
"@angular/compiler-cli": "5.2.11",
"@angular/core": "5.2.11",
"@angular/forms": "5.2.11",
"@angular/http": "5.2.11",
"@angular/platform-browser": "5.2.11",
"@angular/platform-browser-dynamic": "5.2.11",
"@ionic-native/core": "~4.17.0",
"@ionic-native/splash-screen": "~4.17.0",
"@ionic-native/status-bar": "~4.17.0",
Run Code Online (Sandbox Code Playgroud)
每当我尝试在app.module上导入下面的代码时,总会显示我在顶部显示的错误.
StoreDevtoolsModule.instrument({
maxAge: 15
}),
Run Code Online (Sandbox Code Playgroud)
顶部的错误是指第210行我控制台中的这行代码
this.extensionConnection.send(sanitizedAction, sanitizedState);
Run Code Online (Sandbox Code Playgroud)
感谢有人可以提供帮助.提前致谢.
对于我的测试,我试图模拟一个事件流,Observable.of()但当我尝试
const actions$ = Observable.of({});
...
// in the function that is tested
actions$
.filter(action => action.type === 'LOAD_REQUEST')
.first()
.subscribe(() => { ... do something });
Run Code Online (Sandbox Code Playgroud)
我收到以下错误
EmptyError:xxx.js中没有按顺序排列的元素
这只在我使用时发生.first().
如何模拟事件流以使测试不会失败?