在 ngrx/store 中存储 Angular templateRefs
Storing Angular templateRefs inside ngrx/store
我们现在正在为我们的应用构建上下文帮助卡系统。该应用大量使用 ngrx,我们正在努力遵循良好做法。
我们目前正在讨论是否应该在状态中存储卡片内容模板。在我看来,它似乎有点与 ngrx 原则相矛盾。 IE。模板不可序列化,可以从外部进行修改。但这里的问题是卡片内容可能非常复杂,并且可能有多种不同的卡片。因此,如果我们不存储模板,我们可能需要为每种情况创建一个单独的组件并创建一个 {[contentId: string]: Type<ContentComponent>}
映射,以便能够引用具有字符串 ID 的那些组件。
首先,我想问一下(我想这是一个有点自以为是的问题)-也许我的担忧是错误的,在状态中存储 angular 模板这样的结构是正常的吗?
如果这不是一个很好的解决方案,那么如何处理这样的用例?
谢谢你,很抱歉提出自以为是的问题。我知道他们在这里不太受欢迎。
固执己见的问题需要固执己见的答案。我会保持简短。不要在您的商店中存储任何复杂的对象。这不是它的目的。这是关于这个主题的一个很好的read。
Basically what a store should provide is:
- provide an Observable-like pattern for decoupled component interaction
- provide a client container for temporary UI state
- provide a cache for avoiding excessive HTTP requests
- provide a solution for concurrent data modification by multiple actors
您还提到您的卡片内容非常复杂,并且彼此之间存在差异。那么模板绝对不是要走的路。这意味着所有逻辑都包含在一个 component.ts
中。好像有点过分了。
所以组件绝对是正确的选择。我可以想象它们核心中的卡片有一些共享的功能。您可以将此功能放在抽象 class 中,并让您的卡片组件扩展此 class
export abstract class CardComponent {
// some shared logic
}
而一些卡片组件是:
@Component({...})
export class SomeCardComponent extends CardComponent {
constructor() {
super();
}
}
您关于制作包含 Record<string, Type<T>>
的可导出常量映射的建议听起来非常可行,您可以将其与 ngComponentOutlet
or if you want more control by using the ComponentFactoryResolver
结合使用。您可以检查这些链接中的任何一个以获得良好的实现。
另一种方法是使用 ngSwitch
.
基本上,您将拥有使用此开关的根模板:
<ng-container [ngSwitch]="card.id">
<some-card *ngSwitchCase="'some-card'"></some-card>
<other-card *ngSwitchCase="'other-card'"></other-card>
<!-- etc -->
</ng-container>
附带说明一下,如果您想访问父组件内的所有卡片,可以使用一些小技巧。更新您的卡组件以包含提供商:
@Component({
selector: 'some-card',
providers: [
{ provide: CardComponent, useExisting: SomeCardComponent }
]
})
export class SomeCardComponent extends CardComponent { //... }
在您的父组件中,您可以使用 @ViewChildren()
查询它们
@ViewChildren(CardComponent)
cardComponents: QueryList<CardComponent>;
这可能会派上用场,例如,从父级访问共享逻辑。
我猜我没有保持简短
我们现在正在为我们的应用构建上下文帮助卡系统。该应用大量使用 ngrx,我们正在努力遵循良好做法。
我们目前正在讨论是否应该在状态中存储卡片内容模板。在我看来,它似乎有点与 ngrx 原则相矛盾。 IE。模板不可序列化,可以从外部进行修改。但这里的问题是卡片内容可能非常复杂,并且可能有多种不同的卡片。因此,如果我们不存储模板,我们可能需要为每种情况创建一个单独的组件并创建一个 {[contentId: string]: Type<ContentComponent>}
映射,以便能够引用具有字符串 ID 的那些组件。
首先,我想问一下(我想这是一个有点自以为是的问题)-也许我的担忧是错误的,在状态中存储 angular 模板这样的结构是正常的吗?
如果这不是一个很好的解决方案,那么如何处理这样的用例?
谢谢你,很抱歉提出自以为是的问题。我知道他们在这里不太受欢迎。
固执己见的问题需要固执己见的答案。我会保持简短。不要在您的商店中存储任何复杂的对象。这不是它的目的。这是关于这个主题的一个很好的read。
Basically what a store should provide is:
- provide an Observable-like pattern for decoupled component interaction
- provide a client container for temporary UI state
- provide a cache for avoiding excessive HTTP requests
- provide a solution for concurrent data modification by multiple actors
您还提到您的卡片内容非常复杂,并且彼此之间存在差异。那么模板绝对不是要走的路。这意味着所有逻辑都包含在一个 component.ts
中。好像有点过分了。
所以组件绝对是正确的选择。我可以想象它们核心中的卡片有一些共享的功能。您可以将此功能放在抽象 class 中,并让您的卡片组件扩展此 class
export abstract class CardComponent {
// some shared logic
}
而一些卡片组件是:
@Component({...})
export class SomeCardComponent extends CardComponent {
constructor() {
super();
}
}
您关于制作包含 Record<string, Type<T>>
的可导出常量映射的建议听起来非常可行,您可以将其与 ngComponentOutlet
or if you want more control by using the ComponentFactoryResolver
结合使用。您可以检查这些链接中的任何一个以获得良好的实现。
另一种方法是使用 ngSwitch
.
基本上,您将拥有使用此开关的根模板:
<ng-container [ngSwitch]="card.id">
<some-card *ngSwitchCase="'some-card'"></some-card>
<other-card *ngSwitchCase="'other-card'"></other-card>
<!-- etc -->
</ng-container>
附带说明一下,如果您想访问父组件内的所有卡片,可以使用一些小技巧。更新您的卡组件以包含提供商:
@Component({
selector: 'some-card',
providers: [
{ provide: CardComponent, useExisting: SomeCardComponent }
]
})
export class SomeCardComponent extends CardComponent { //... }
在您的父组件中,您可以使用 @ViewChildren()
@ViewChildren(CardComponent)
cardComponents: QueryList<CardComponent>;
这可能会派上用场,例如,从父级访问共享逻辑。
我猜我没有保持简短