typescript 如何在旋转组件类型时最大限度地减少重复绑定?

wgx48brx  于 2023-06-07  发布在  TypeScript
关注(0)|答案(1)|浏览(169)

我有一系列的数据对象,它们都继承自同一个基类。

  1. export interface DataObjectBase {
  2. type: string;
  3. /* ... other shared fields */
  4. }
  5. export interface DataObjectA extends DataObjectBase { /* ... */ }
  6. export interface DataObjectB extends DataObjectBase { /* ... */ }
  7. export interface DataObjectC extends DataObjectBase { /* ... */ }

对象类型由每个对象上存在的'type'属性的值标识。例如,如果一个对象的type属性是"A",我就可以安全地将其强制转换为DataObjectA
对于这些对象类型中的每一种,我都有一个组件。这些组件都继承自同一个基类,因此也有共享的@Input()@Output()绑定,但也可能有自己的显式绑定。
例如:

  1. export class MyComponentBase<T extends DataObjectBase> {
  2. @Input() public data: T;
  3. @Input() public someValue: string;
  4. @Input() public someOtherValue: number;
  5. @Output() public someOtherValueChanged: EventEmitter<number>;
  6. @Output() public someEvent: EventEmitter<string>;
  7. }
  8. @Component({selector: 'component-a', templateUrl: './component-a.template.html'})
  9. export class MyComponentA extends MyComponentBase<DataObjectA> { /* ... */ }
  10. @Component({selector: 'component-b', templateUrl: './component-b.template.html'})
  11. export class MyComponentB extends MyComponentBase<DataObjectB> { /* ... */ }
  12. @Component({selector: 'component-c', templateUrl: './component-c.template.html'})
  13. export class MyComponentC extends MyComponentBase<DataObjectC> { /* ... */ }

每个子类化的组件都有自己的模板,并使用内部绑定做不同的事情。
在我的主机组件中,我使用ngSwitch来交换基于数据的组件实现,然而,我发现我需要实现大量重复的绑定样板:

  1. <ng-container [ngSwitch]="data.type">
  2. <component-a
  3. *ngSwitchCase="'A'"
  4. #object
  5. [data]="data"
  6. [someValue]="someValue"
  7. [(someOtherValue)]="someOtherValue"
  8. (someEvent)="onSomeEvent($event)"></component-a>
  9. <component-b
  10. *ngSwitchCase="'B'"
  11. #object
  12. [data]="data"
  13. [someValue]="someValue"
  14. [(someOtherValue)]="someOtherValue"
  15. (someEvent)="onSomeEvent($event)"></component-a>
  16. <component-c
  17. *ngSwitchCase="'C'"
  18. #object
  19. [data]="data"
  20. [someValue]="someValue"
  21. [(someOtherValue)]="someOtherValue"
  22. (someEvent)="onSomeEvent($event)"></component-a>
  23. </ng-container>

我希望能够将重复的#object [data]="data" [someValue]="someValue" [(someOtherValue)]="someOtherValue" (someEvent)="onSomeEvent($event)"简化为类似[sharedBindings]的东西,这样我就可以做更多的事情:

  1. <ng-container [ngSwitch]="data.type">
  2. <component-a *ngSwitchCase="'A'" [sharedBindings]></component-a>
  3. <component-b *ngSwitchCase="'B'" [sharedBindings]></component-b>
  4. <component-c *ngSwitchCase="'C'" [sharedBindings] [cSpecificValue]="foo"></component-c>
  5. </ng-container>

有比这更多的绑定,我已经有大约12个不同的组件和计数。尽可能保持组件无状态意味着这变得越来越麻烦。如何避免重复所有这些绑定?
我尝试创建一个使用to @HostBinding绑定到值的指令:

  1. @Directive({selector: '[sharedBindings]'})
  2. export class SharedBindingsDirective {
  3. @Input('sharedBindings') public component: MyComponentBase;
  4. @HostBinding('data')
  5. public get data(): DataObjectBase {
  6. return this.component.data;
  7. }
  8. }

但是,当然,您似乎无法绑定到@Input@Output属性(我也无法想象在主机组件中也表示#object的方法,以便可以将其作为@ViewChild访问)。
有没有什么方法可以在保持组件本身的多态性的同时合并或折叠重复的绑定?

xqkwcwgp

xqkwcwgp1#

我认为你可以使用angular的ComponentFactoryResolver来动态地创建你的组件,而不是在html中创建一个switch case。您也可以将此逻辑放在指令而不是组件中。您可以执行另一个切换用例来绑定未共享的额外值。

相关问题