加载组件时如何使用 NGRX 检索数据(如文件列表数组)
How to retrieve data (like an array of file list) using NGRX when component is loaded
我有一个场景,我想在使用 NGRX 加载组件时显示一些数组(例如:文件列表)。
所以我所做的是创建如下两个动作
GET_FILES => GetFiles as class
SET_FILES => 将文件设置为 class
和一个维护状态的减速器
export interface State {
files: Files[];
}
const initialState: State = {
files: []
};
export function filesReducer(
state: State = initialState,
action: FilesAction.FilesAction
) {
switch (action.type) {
case FilesAction.GET_FILES:
return {
...state
};
case FilesAction.SET_FILES:
const files: Files[] = action.payload;
return {
...state,
...files
};
default:
return state;
}
}
然后会有一个 effect 获取休息 api 调用以获取文件列表,然后 effect 将调度 SET_FILES 操作。
@Effect()
getFiles = this.action$.pipe(
ofType(FilesAction.GET_FILES),
switchMap(() => {
return this.http.get<Files[]>(environment.baseURI + 'api/get-files');
}),
map(filesState => {
return new FilesAction.SetFiles(filesState);
})
);
当组件加载到 ngOnInit 上时,我们可以分派一个 SET_FILES 的动作,它会执行一个效果,然后负责分派另一个 SET_FILES 的动作。
export class FileListComponent implements OnInit {
iFileId: number = 0;
fileList: Files[] = [];
constructor(private store: Store<fromApp.AppState>) {
//Problem Area
this.store.select('files').subscribe(files => {
this.fileList = files.files;
console.log('FileList:');
console.log(this.fileList);
});
}
ngOnInit(): void {
this.store.dispatch(new FilesActions.GetFiles(this.iFileId));
}
}
这里,问题是我能够成功地在 ngOnInit 上发送操作,如果我 console.log 那么我将获得文件列表,但是我如何将它存储在一个变量中,就像我试图在构造函数 ?
在您的组件中,ts 将对选择器结果的引用存储在一个可观察对象中:
export class FileListComponent implements OnInit {
iFileId: number = 0;
fileList$ = this.store.select('files'); // <<<-- add this
constructor(private store: Store<fromApp.AppState>) {}
ngOnInit(): void {
this.store.dispatch(new FilesActions.GetFiles(this.iFileId));
}
}
在您的模板中:
<p *ngIf="fileList$ | async as fileList" *ngFor="let file of fileList.files">
{{ file }}
</p>
注意 ngIf.. as
语法来订阅并检查发出的值是否真实 - 然后您可以安全地在 ngFor
.
中使用 fileList
其他推荐
你的 reducer 不需要 FilesAction.GET_FILES
case,因为它不会改变状态。
在触发它们的相关事件之后命名你的减速器(参见 https://2018.ng-conf.org/sessions/good-action-hygiene-ngrx/ 4:30):
GET_FILES => FILES_REQUESTED
SET_FILES => FILES_LOADED
我有一个场景,我想在使用 NGRX 加载组件时显示一些数组(例如:文件列表)。
所以我所做的是创建如下两个动作
GET_FILES => GetFiles as class
SET_FILES => 将文件设置为 class
和一个维护状态的减速器
export interface State {
files: Files[];
}
const initialState: State = {
files: []
};
export function filesReducer(
state: State = initialState,
action: FilesAction.FilesAction
) {
switch (action.type) {
case FilesAction.GET_FILES:
return {
...state
};
case FilesAction.SET_FILES:
const files: Files[] = action.payload;
return {
...state,
...files
};
default:
return state;
}
}
然后会有一个 effect 获取休息 api 调用以获取文件列表,然后 effect 将调度 SET_FILES 操作。
@Effect()
getFiles = this.action$.pipe(
ofType(FilesAction.GET_FILES),
switchMap(() => {
return this.http.get<Files[]>(environment.baseURI + 'api/get-files');
}),
map(filesState => {
return new FilesAction.SetFiles(filesState);
})
);
当组件加载到 ngOnInit 上时,我们可以分派一个 SET_FILES 的动作,它会执行一个效果,然后负责分派另一个 SET_FILES 的动作。
export class FileListComponent implements OnInit {
iFileId: number = 0;
fileList: Files[] = [];
constructor(private store: Store<fromApp.AppState>) {
//Problem Area
this.store.select('files').subscribe(files => {
this.fileList = files.files;
console.log('FileList:');
console.log(this.fileList);
});
}
ngOnInit(): void {
this.store.dispatch(new FilesActions.GetFiles(this.iFileId));
}
}
这里,问题是我能够成功地在 ngOnInit 上发送操作,如果我 console.log 那么我将获得文件列表,但是我如何将它存储在一个变量中,就像我试图在构造函数 ?
在您的组件中,ts 将对选择器结果的引用存储在一个可观察对象中:
export class FileListComponent implements OnInit {
iFileId: number = 0;
fileList$ = this.store.select('files'); // <<<-- add this
constructor(private store: Store<fromApp.AppState>) {}
ngOnInit(): void {
this.store.dispatch(new FilesActions.GetFiles(this.iFileId));
}
}
在您的模板中:
<p *ngIf="fileList$ | async as fileList" *ngFor="let file of fileList.files">
{{ file }}
</p>
注意 ngIf.. as
语法来订阅并检查发出的值是否真实 - 然后您可以安全地在 ngFor
.
fileList
其他推荐
你的 reducer 不需要
FilesAction.GET_FILES
case,因为它不会改变状态。在触发它们的相关事件之后命名你的减速器(参见 https://2018.ng-conf.org/sessions/good-action-hygiene-ngrx/ 4:30):
GET_FILES => FILES_REQUESTED
SET_FILES => FILES_LOADED