我想为我使用 rxjs 的效果进行 http 调用。现在我的问题是我想像{ type: LoaderActions.LOADER_START }
在 http 调用之前一样调度另一个动作。所以用户可以在请求 Http 调用时看到加载屏幕,一旦请求完成,我想调度另一个动作{ type: LoaderActions.LOADER_END }
。
如何使用 rxjs 运算符实现此目的?我对何时在 rxjs 中使用哪个运算符感到非常困惑。
auth.effects.ts
import { Injectable } from '@angular/core';
import { Observable, of, concat } from 'rxjs';
import { Action, Store } from '@ngrx/store';
import { Actions, Effect, ofType } from '@ngrx/effects';
import * as AuthActions from './auth.actions';
import * as LoaderActions from '../../loader/store/loader.actions';
import {
map,
mergeMap,
switchMap,
debounce,
debounceTime,
tap,
startWith
} from 'rxjs/operators';
import { …
Run Code Online (Sandbox Code Playgroud) 我正在运行 Angular 9、@ngrx/store
v9 和 SSR,但我只是npm start
在开发中运行,所以 SSR 并不是真正的因素。
我刚刚添加了 NGRX Store 并为某些产品制作了我的动作、减速器和效果。运行此命令后,我现在收到错误:Error: Can't resolve all parameters for ProductsEffects: (?, ?).
ProductsEffects类构造函数如下:
constructor(private actions$: Actions<ProductsActions>,
private appService: AppService) {
}
Run Code Online (Sandbox Code Playgroud)
AppService 类标记为@Injectable({providedIn: 'root'})
,并且actions$
应该从 NGRX Store 注入。
这是来自的导入部分app.module
:
const EFFECTS = [ProductsEffects];
...
imports: [
BrowserModule.withServerTransition({appId: 'my-app'}),
BrowserAnimationsModule,
HttpClientModule,
NgxSpinnerModule,
AgmCoreModule.forRoot({
apiKey: 'redacted'
}),
SharedModule,
routing,
StoreModule.forRoot(reducers, {
metaReducers,
runtimeChecks: {
strictStateImmutability: true,
strictActionImmutability: true
}
}),
EffectsModule.forRoot(EFFECTS),
StoreRouterConnectingModule.forRoot()
],
Run Code Online (Sandbox Code Playgroud)
以下是相关部分 …
我没有登录页面,这是 sso 调用
在应用程序组件中,我已经调度了一个操作来加载服务器端令牌调用并获取令牌,并且根据用户角色,我可以激活路由中的防护。如果守卫激活返回 true,我将进入仪表板页面。
在仪表板页面中,我在浏览器 URL 中有一个刷新,可以激活在登录操作效果之前执行,因此可以激活返回 false 且页面显示空白。
在仪表板中有子路由,也有一些子链接,例如产品仪表板/产品,也有激活的防护,但可以在登录调度操作影响成功调用之前激活返回 false。
谁能帮助我我做错了什么?
这里是路由,
{
path: '',
component: HomeComponent,
canActivate:[AuthGuard],
children: [
{
path: 'product',
loadChildren: () => productModule
},
{
path: 'order',
loadChildren: () => orderModule
}
]
},
Run Code Online (Sandbox Code Playgroud)
这是激活方法:这里我从效果调用中获得成功,同时从 app.component 调度一个操作:
canActivate(): Observable<boolean> {
return this.store.select(appState => appState.auth.isAuthenticated)
.pipe(map(authUser => {
if (!authUser) {
return authUser;
}
return authUser;
}))
}
Run Code Online (Sandbox Code Playgroud)
应用程序组件:
ngOnInit(){
this.onSubmit();
}
onSubmit(): void {
const payload = {
email: 'test@test.com',
password: 'admin'
};
alert('dispatch …
Run Code Online (Sandbox Code Playgroud) ngrx-effects angular ngrx-store-4.0 angular-guards angular-ngrx-data
有没有办法避免取消前一个的影响?
我需要去做:
this.tagsStoreService.initTagsForFamilyId(this.tagFamily.id)
Run Code Online (Sandbox Code Playgroud)
我有这样的效果:
@Effect() initTagsForFamilyId$: Observable<Action> = this.actions$
.pipe(
ofType<InitTagsForFamilyIdAction>(TagsStateActionTypes.INIT_TAGS_FOR_FAMILY_ID_ACTION),
switchMap(params => {
// this.loadingService.showLoading();
return this.tagsService.initTagsForFamilyId(params.payload)
.pipe(
exhaustMap((data) => {
this.loadingService.hideLoading();
return [
new InitTagsForFamilyIdSuccessAction({ ...data }),
];
}),
catchError(error => {
// this.loadingService.hideLoading();
return of(new TagsFailureAction({ error }));
}),
);
}),
);
Run Code Online (Sandbox Code Playgroud)
预先感谢您的帮助;-)
这里总共有一个Redux noob,我在将数据从商店中取出以便在我的视图中使用时遇到了一些困难.这是我的行动,减速器等.
genre.model.ts
export interface Genre {
id: string;
title: string;
description: string;
slug: string;
error: string;
}
export const initialState: Genre = {
id: '',
title: '',
description: '',
slug: '',
error: null
};
Run Code Online (Sandbox Code Playgroud)
genre.service.ts
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Http } from '@angular/http';
import {environment} from "../../../environments/environment";
import {Genre} from "./genre.model";
@Injectable()
export class GenreService {
apiUrl = environment.apiUrl + environment.apiVersion + '/';
constructor(private http: Http) { }
/** …
Run Code Online (Sandbox Code Playgroud) 我需要向 API 发送一个 put 请求,ngrx/effect
但该请求需要 id 和内容,以便 MongoDB 能够找到帖子。
这是代码,我尝试设置两个操作有效负载:
export class UpdatePost implements Action {
readonly type = UPDATE_POST
constructor(public payload: string & Post ) { }
}
Run Code Online (Sandbox Code Playgroud)
这是效果:
@Effect()
editPost$: Observable<Action> = this.actions$
.ofType(PostActions.UPDATE_POST)
.map((action: PostActions.UpdatePost) => action.payload)
.switchMap((?) => {
return this.postService.editPost(id, post);
})
.map(editedpost => ({type: PostActions.UPDATE_POST_SUCCESS, payload: editedpost}))
}
Run Code Online (Sandbox Code Playgroud)
editPost()
需要两个参数:id 和 content。
我想我的操作有效负载应该以其他方式设置,我是新手,ngrx
所以欢迎提出建议。
我有simle特效类,必须从Firebase获取一些数据并发送新动作.
@Injectable()
export class TripsEffects {
constructor(private actions$: Actions, private afAuth: AngularFireAuth ) {}
@Effect()
loadTrips$ = this.actions$.ofType(TripsActionsTypes.LOAD_TRIPS)
.pipe(
switchMap(() => {
return this.afAuth.authState.pipe(
map(user => new LoadTripsSuccess(user))
);
})
);
}
Run Code Online (Sandbox Code Playgroud)
但我得到错误Actions must have a type property
.当用户登录时,它们被重定向到Trips页面,而在Trips组件中,我将调度一个动作来加载行程.这是我的行动:
export enum TripsActionsTypes {
LOAD_TRIPS = '[Trips] Load Trips',
LoadTripsSuccess = '[Trips] Load Trips Success',
LoadTripsFailure = '[Trips] Load Trips Failure'
}
export class LoadTrips implements Action {
type: TripsActionsTypes.LOAD_TRIPS;
}
export class LoadTripsSuccess implements Action {
type: TripsActionsTypes.LoadTripsSuccess;
constructor(public …
Run Code Online (Sandbox Code Playgroud) 我有这种效果,我正在尝试使用计时器每x秒轮询一次数据。但是我不知道计时器应该如何与数据流交互。我尝试在顶部添加另一个switchMap,但随后无法将操作和有效负载传递给第二个switchmap。有任何想法吗?
我看了这篇文章,但情况有所不同。我正在通过需要访问的操作传递有效负载,并且正在使用ngrx 6。
@Effect()
getData = this.actions$
.ofType(appActions.GET_PLOT_DATA)
.pipe(
switchMap((action$: appActions.GetPlotDataAction) => {
return this.http.post(
`http://${this.url}/data`,
action$.payload.getJson(),
{responseType: 'json', observe: 'body', headers: this.headers});
}),
map((plotData) => {
return {
type: appActions.LOAD_DATA_SUCCESS,
payload: plotData
}
}),
catchError((error) => throwError(error))
)
Run Code Online (Sandbox Code Playgroud) 我的应用程序中有不同的选择器,但由于某种原因,当我的商店发生更改时,这个特定的选择器不会更新,我不知道为什么。行的代码selectDataStream
在第一次之后永远不会运行,随后的存储更改并且没有任何反应。我看到我的新值已在商店中更新。
成分:
ngAfterViewInit(): void {
if (this.fields && this.fields.length > 0) {
this.store$.select<any[]>(getConnections(this.connectorId))
.takeUntil(this.onDestroy$).subscribe(connections => {
this.selectDataStream.next(connections);
this.cdRef.detectChanges();
});
}
}
Run Code Online (Sandbox Code Playgroud)
减速器代码:
const model = state.connectionresults[connectionId];
const updatedstate = {
...state,
connectionresults: {
...state.connectionresults,
[connectionId]: {
...model,
connections: [...payload]
}
}
};
return {
...updatedstate
};
Run Code Online (Sandbox Code Playgroud)
选择器:
export const selectConnectionResults = createSelector(
selectFinderData,
(state: FinderState) => state.connectionresults
);
export const getConnections = (id) => createSelector(selectConnectionResults, entities => {
return entities[id];
});
Run Code Online (Sandbox Code Playgroud)
我做错了什么导致选择器无法触发?