组合多个可管道化的NgRx选择器

huangapple go评论76阅读模式
英文:

Combining multiple pipeable NgRx selectors

问题

可以将多个可管道选择器以与组合多个常规选择器相同的方式组合吗?

组合常规选择器:

export const selectActiveOrganization = createSelector(
    selectOrganizations,
    selectActiveOrganizationId,
    (organizations, activeOrgId) => organizations[activeOrgId],
);

上面有两个选择器selectOrganizationsselectActiveOrganizationId,它们传递给createSelector来创建一个selectActiveOrganization

问题在于selectActiveOrganization也可能返回undefined


现在让我们将其重写为可管道选择器:

const _selectActiveOrganization = createSelector(
    selectOrganizations,
    selectActiveOrganizationId,
    (organizations, activeOrgId) => organizations[activeOrgId],
);

export const selectActiveOrganizationPipeable = pipe(
    select(_selectActiveOrganization),
    filter(activeOrg => !!activeOrg),
);

selectActiveOrganizationPipeable中,我们改进了selectActiveOrganization选择器,只有在存在任何活动组织时才发出值。

到目前为止一切都很好。

现在假设我们想要在我们的可管道选择器的基础上构建一个新的选择器,它仅返回组织名称。

export const selectActiveOrganizationNamePipeable = pipe(
    select(selectActiveOrganizationPipeable),
    map(organization => organization.name), // --> TS错误:类型'Observable<Organization>'上不存在属性'name'。ts(2339)
);

是否有一种方法可以重用现有的selectActiveOrganizationPipeable?(类似于我们重用常规选择器)

英文:

Is it possible to combine multiple pipeable selectors the same way we can combine multiple regular selectors?

Combining regular selectors:

export const selectActiveOrganization = createSelector(
    selectOrganizations,
    selectActiveOrganizationId,
    (organizations, activeOrgId) =&gt; organizations[activeOrgId],
);

Above there are two selectors selectOrganizations and selectActiveOrganizationId, which are passed into createSelector to create a selectActiveOrganization.

Problem here is that selectActiveOrganization can also return undefined.


Now let's rewrite this to pipeable selector:

const _selectActiveOrganization = createSelector(
    selectOrganizations,
    selectActiveOrganizationId,
    (organizations, activeOrgId) =&gt; organizations[activeOrgId],
);

export const selectActiveOrganizationPipeable = pipe(
    select(_selectActiveOrganization),
    filter(activeOrg =&gt; !!activeOrg),
);

In selectActiveOrganizationPipeable we improved the selectActiveOrganization selector to only emit value if there is any active organization.

So far so good.

Now let's say we want to build on to of our pipeable selector and create a new one which is returning only the organization name.

export const selectActiveOrganizationNamePipeable = pipe(
    select(selectActiveOrganizationPipeable),
    map(organization =&gt; organization.name), // --&gt; TS ERROR: Property &#39;name&#39; does not exist on type &#39;Observable&lt;Organization&gt;&#39;.ts(2339)
);

Is there a way to reuse existing selectActiveOrganizationPipeable? (similarly as we reuse regular selectors)

答案1

得分: 3

以下是翻译好的部分:

"Something like this should work.
You can use the previous pipe within the new pipe.

  pipe(
    selectActiveOrganizationPipeable,
    map(organization =&gt; organization.name)
  );
```"

<details>
<summary>英文:</summary>

Something like this should work.
You can use the previous pipe within the new pipe.

export const selectActiveOrganizationNamePipeable =
pipe(
selectActiveOrganizationPipeable,
map(organization => organization.name)
);


</details>



huangapple
  • 本文由 发表于 2023年7月17日 22:57:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76705720.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定