如何在执行组件模板之前处理ngxs observable
How to process ngxs observable before component template is executed
我有一个使用 @ngxs/store
node.js 包 v3.6.2 的 angular 10 项目,我正在尝试在服务 class 中进行状态订阅,过程结果立即投入使用,然后将结果传递给组件。
我的服务 class 目前无法使用:
import { Injectable } from '@angular/core';
import { Store } from '@ngxs/store';
import { Models } from './models/document.model';
import { Observable } from 'rxjs';
import { async } from 'rxjs/internal/scheduler/async';
@Injectable({
providedIn: 'root'
})
export class ProjectService {
documents$: Observable<Models.Document[]>;
activeDocumentTitle$: Observable<string>;
activeDocument: Models.Document;
activeDocumentTitle: string;
constructor(private store: Store) {
this.activeDocumentTitle$ = this.store.select(state => state.meta.activeDocumentTitle);
this.documents$ = this.store.select(state => state.project.documents);
}
getActiveDocument(): Models.Document {
(this.documents$ | async).filter(
document => document.title === (this.activeDocumentTitle$ | async))[0];
return this.activeDocument;
}
}
我想做什么:我想对一个对象数组执行 select 并稍后将该数组过滤为一个对象属性 匹配提供的字符串;最后,我想将这个过滤后的数组的第一个元素传递给一个组件。我的基本问题是 'can this be achieved?'.
我已经用谷歌搜索死了,并且彻底研究了官方文档 (ngxs documentation),看来你能得到由 observable selected 的实际数据的唯一方法是在组件模板如下:
{{ observableVar | async }}
这真的是您可以使用 ngxs 与 observables 交互的唯一方式吗 - 在跳转到 html 模板之前您根本不能弄乱数据?
此问题已在 中得到解答。 subscribe()
方法正是我所追求的。
从 NGXS 的角度来看,这里使用服务 class 是多余的 - NGXS 存储保存状态,因此您不需要服务 class 也保存状态(如 activeDocument 或 activeDocumentTitle ).
而是定义一个 Selector
,它允许您组合这两种状态并将结果映射到您需要的格式。例如。从您的示例代码中推断出一点,在 ProjectsState
中定义一个选择器,例如:
@Selector([ProjectsState, MetaState])
static activeDocument(projectsState: ProjectStateModel, metaState: MetaStateModel) {
if (!metaState.activeDocumentTitle) {
return null;
}
return projectsState.project.documents.find(d => d.title === metaState.activeDocumentTitle);
}
然后在您的组件中,访问该选择器
@Selector(ProjectsState.activeDocument) activeDocument$: Observable<Document>;
然后在组件模板中使用activeDocument$ | async
访问它
这比必须在组件中手动订阅(和取消订阅)更好。
在 Joining Selector and Meta Selector 文档中查看更多选项。
我有一个使用 @ngxs/store
node.js 包 v3.6.2 的 angular 10 项目,我正在尝试在服务 class 中进行状态订阅,过程结果立即投入使用,然后将结果传递给组件。
我的服务 class 目前无法使用:
import { Injectable } from '@angular/core';
import { Store } from '@ngxs/store';
import { Models } from './models/document.model';
import { Observable } from 'rxjs';
import { async } from 'rxjs/internal/scheduler/async';
@Injectable({
providedIn: 'root'
})
export class ProjectService {
documents$: Observable<Models.Document[]>;
activeDocumentTitle$: Observable<string>;
activeDocument: Models.Document;
activeDocumentTitle: string;
constructor(private store: Store) {
this.activeDocumentTitle$ = this.store.select(state => state.meta.activeDocumentTitle);
this.documents$ = this.store.select(state => state.project.documents);
}
getActiveDocument(): Models.Document {
(this.documents$ | async).filter(
document => document.title === (this.activeDocumentTitle$ | async))[0];
return this.activeDocument;
}
}
我想做什么:我想对一个对象数组执行 select 并稍后将该数组过滤为一个对象属性 匹配提供的字符串;最后,我想将这个过滤后的数组的第一个元素传递给一个组件。我的基本问题是 'can this be achieved?'.
我已经用谷歌搜索死了,并且彻底研究了官方文档 (ngxs documentation),看来你能得到由 observable selected 的实际数据的唯一方法是在组件模板如下:
{{ observableVar | async }}
这真的是您可以使用 ngxs 与 observables 交互的唯一方式吗 - 在跳转到 html 模板之前您根本不能弄乱数据?
此问题已在 subscribe()
方法正是我所追求的。
从 NGXS 的角度来看,这里使用服务 class 是多余的 - NGXS 存储保存状态,因此您不需要服务 class 也保存状态(如 activeDocument 或 activeDocumentTitle ).
而是定义一个 Selector
,它允许您组合这两种状态并将结果映射到您需要的格式。例如。从您的示例代码中推断出一点,在 ProjectsState
中定义一个选择器,例如:
@Selector([ProjectsState, MetaState])
static activeDocument(projectsState: ProjectStateModel, metaState: MetaStateModel) {
if (!metaState.activeDocumentTitle) {
return null;
}
return projectsState.project.documents.find(d => d.title === metaState.activeDocumentTitle);
}
然后在您的组件中,访问该选择器
@Selector(ProjectsState.activeDocument) activeDocument$: Observable<Document>;
然后在组件模板中使用activeDocument$ | async
这比必须在组件中手动订阅(和取消订阅)更好。
在 Joining Selector and Meta Selector 文档中查看更多选项。