这是在 ngrx 中获取当前状态的解决方案。这个例子很简单——你只需使用take(1). 但是在 rxjs 文档中take它说:
从可观察序列的开头返回指定数量的连续元素
为什么取第一个值会得到当前状态(即最后一个值)?
此外,我在使用Subject.
我正在使用 ngrx 来存储我的用户状态。对于用户状态,我指的是IUser具有一些用户属性的类对象。
我已经设置了几个动作 ( 'USER_LOGIN', 'USER_LOGIN_SUCCESS' and 'USER_LOGJN_FAILED')。
目前,当USER_LOGIN_SUCCESS调度an 时,reducer 将新用户信息分配给我的IStore.userngrx store 字段。当它改变时:
this.user$ = this.store$.select(state => state.user);
this.userSub = this.user$.subscribe(
(user: IUser) => {
if (user.id != null)
this.router.navigate(['/app']);
}
);
Run Code Online (Sandbox Code Playgroud)
如您所见,我只检查我更改的用户的状态是否是user.id != null,然后导航到我的/app路线。
有没有使用更优雅的方式来做到这一点。例如,
IStore.user字段的显式订阅?'USER_LOGIN_SUCCESS'分派操作 ( )时,我是否可以直接导航到路线?有任何想法吗?
我正在查看NgRx 提供的示例应用程序的代码。我注意到示例应用程序中的每个 reducer 函数都有一个返回值,该返回值由该State特定 reducer的接口输入。例如,书籍减速器具有以下代码:
export interface State {
ids: string[];
entities: { [id: string]: Book };
selectedBookId: string | null;
}
export const initialState: State = {
ids: [],
entities: {},
selectedBookId: null,
};
export function reducer(
state = initialState,
action: book.Actions | collection.Actions
): State {
Run Code Online (Sandbox Code Playgroud)
后来,我读了一本关于 NgRx 的书,名为Oren Farhi 的《使用 Angular 和 NgRx进行响应式编程》,并偶然发现了一段代码片段,显示了一个 reducer 函数的公共主体结构(第 24-25 页)公共结构的代码示出了减速函数的返回值作为由正在键入ActionReducer与State作为类型参数(称为SomeInterface而非State在这种情况下):
export interface …Run Code Online (Sandbox Code Playgroud) 这应该是一个简单的解决方案,但我似乎无法把它放在一起......
我有一个返回 Promise 的函数和另一个返回 Promise 的函数。我需要使用前者的返回值调用后者,但我还需要在转换链的末尾使用这两个值。我已经阅读了一些关于 mergeMap 和 forkJoin 的文档,但我似乎无法使用它们来获得我需要的结果:
function getBlob(id: string): Promise<Blob>;
function blobToBase64(imageBlob: Blob): Promise<string>;
// ...
// This is what I tried but I getting Observables back after the forkJoin instead of the actual values
return Observable.fromPromise(getBlob(id))
.map((blob) => return Observable.forkJoin([Observable.of(blob), Observable.fromPromise(blobToBase64)])
// data[0] and data[1] are undefined but it looks like data is actually an Observable from forkJoin.
.map((data) => console.log(`Here is ${data[0]} and ${data[1]}`);
Run Code Online (Sandbox Code Playgroud)
谁能解释一下如何在最后得到 blob 和 base64 值?
我真的很喜欢干净的 API this.store.select('media', 'games');
我不需要用 来创建任何选择器createSelector(),也不需要导入任何东西。我觉得当项目变大时,选择器成为了这个伟大的中间层。media.selectors.ts成为一个整体文件。
我最终让很多选择器做简单的事情,而不是:
this.store.select('media', 'games');
Run Code Online (Sandbox Code Playgroud)
我愿意:
import * as fromMedia '../media'
this.store.select(fromMedia.getAllGamesSelector());
Run Code Online (Sandbox Code Playgroud)
和同上,用于movies例如:
import * as fromMedia '../media'
this.store.select(fromMedia.getAllMoviesSelector());
Run Code Online (Sandbox Code Playgroud)
我知道createSelector()记忆化有好处,但我非常怀疑使用简单的选择strings会慢得多......
我读过的每个指南都要求您必须使用 createSelector()
所以我的问题是,什么时候使用合适createSelector()?可以使用字符串选择器,还是不赞成并且是不好的做法?
干(不要重复自己)
假设我在我的应用程序中使用了很多代码:
observable$.pipe(
tap(value => console.log(value)),
map(value => value * 5),
... more repeated stuff
)
Run Code Online (Sandbox Code Playgroud)
假设值5在代码的某些部分是不同的,但其他一切都是相同的.我可以以某种方式功能化/做一些事情,使其可重复使用,以避免复制粘贴问题?
我可以这样做吗?
observable$.pipe(
getReusedOperators(7), // this would pipe to all above operators using 7 instead of 5
tap((value) => console.log('im not reused and my value is', value)),
....
)
Run Code Online (Sandbox Code Playgroud)
这里最好的方法是什么?对不起,我的问题不是很好,但希望你能得到这个想法.
我正在使用 ngrx 在我的 ionic 3.9.2 应用程序中实现应用程序状态(使用本教程作为指导:https ://gonehybrid.com/a-beginners-guide-to-using-ngrx-in-an-ionic- 2-app-part-1/ )
当我尝试运行该应用程序时,我目前收到此错误:
typescript: ...foo/bar/node_modules/@ngrx/effects/src/on_run_effects.d.ts, line: 9
A computed property name in a type literal must directly refer to a built-in symbol.
Run Code Online (Sandbox Code Playgroud)
错误是参考以下代码块:
export declare function isOnRunEffects(sourceInstance: {
[onRunEffectsKey]?: onRunEffectsFn;
}): sourceInstance is OnRunEffects;
Run Code Online (Sandbox Code Playgroud)
我正在使用 ngrx 效果版本 6.1.0。
感谢任何和所有的帮助,因为我承认这一点很难过。谢谢。
编辑
我正在使用打字稿版本 3.0.1
我有以下减速器:
case ProductionCommentActionTypes.EditCommentSuccess: {
return adapter.updateOne(action.payload, state);
}
Run Code Online (Sandbox Code Playgroud)
其中有效负载是以下对象:
{
id: number,
changes: {
id: number;
avatar: string;
createdAt: Date;
createdBy: string;
body: string;
discipline: string;
isConcern: boolean;
isResolved: boolean;
plan_Id: number;
resolution: {
id: number;
comment_Id: number;
avatar: string;
createdAt: Date;
createdBy: string;
body: string;
}
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,当我去更新对象时,我可以清楚地看到 action.payload 有我预期的数据。我已经检查了 action.payload 和效果:
@Effect()
resolveProductionConcernSuccess$: Observable<Action> = this.actions$
.ofType<ResolveConcernSuccess>(ProductionCommentActionTypes.ResolveConcernSuccess).pipe(
// Performing a get rather than an edit as the comment should have already
// been updated in the service …Run Code Online (Sandbox Code Playgroud) 找了很长时间,但找不到任何东西。
我有一个这样的模板:
<learning-navigation *ngIf="(_navigationSelectedSafe$ | async) == _navigationLayout.location" [(selectMode)]="_navigationModeSelected"></learning-navigation>
Run Code Online (Sandbox Code Playgroud)
在哪里:
private _navigationSelected$: Observable<string>;
private _navigationSelectedSafe$ = new EventEmitter<any>(true);
...
this._navigationSelected$.subscribe(res => {
...
this._navigationSelectedSafe$.emit(res)
});
Run Code Online (Sandbox Code Playgroud)
学习导航的输入是一个二传手:
@Input()
set selectMode(mode: number) {
this.mode = mode;
}
Run Code Online (Sandbox Code Playgroud)
这会导致错误:
ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'selectMode: null'. Current value: 'selectMode: 1'.
Run Code Online (Sandbox Code Playgroud)
我已经尝试将 EventEmitter 更改为 BehaviourSubject,在 ngInit 和 ngAfterChecked 之后强制 detectChanges()(尽管即使它工作也不是最佳的)并将其包装在一个容器中,试图将模式直接异步传递到组件中,同时只是用一个额外的 if 来控制显示。
当前的解决方案有效,似乎没有任何副作用,但无论模式何时更改,它都会引发错误。谢谢
我正在尝试使用ngrx-data-lab作为我项目的示例。
这是我使用的项目的stackblitz。
我无法使用我正在使用的服务器的实际 url。该网址属于我公司。但是发生的事情是服务器将随机生成的数据返回给应用程序。问题是存储中的实体不会被替换,而是被加起来。每次刷新英雄页面时,服务器都会带来新数据并将其与旧数据连接起来。
在entity-store.module.ts 中,我将defaultDataServiceConfig root 和 Hero urls更改为我的服务器。getAll() 有效,但正如我再次所说,它将数据连接到旧数据。
root: 'api', // default root path to the server's web api
// Optionally specify resource URLS for HTTP calls
entityHttpResourceUrls: {
// Case matters. Match the case of the entity name.
Hero: {
// You must specify the root as part of the resource URL.
entityResourceUrl: 'api/hero/',
collectionResourceUrl: 'api/heroes/'
}
},
Run Code Online (Sandbox Code Playgroud)
如何让 getAll 替换旧数据而不是连接它?
ngrx ×10
angular ×9
rxjs ×3
ngrx-effects ×2
ngrx-store ×2
typescript ×2
javascript ×1
observable ×1