【问题标题】:How to use union types in the HTML template side of an Angular component如何在 Angular 组件的 HTML 模板端使用联合类型
【发布时间】:2023-03-11 17:40:02
【问题描述】:

在 Angular 组件的 HTML 部分,我想在不同条件下显示复选框或图标。使用许可模型{ checked?: boolean; icon?: string },我可以这样做:

<input type="checkbox" [(ngModel)]="item.checked" *ngIf="!item.icon">
<i class="{{item.icon}}" *ngIf="item.icon">

此模型启用无效状态,例如同时具有 checkedicon。拥有更强大的模型可能依赖于联合类型:{ checked: boolean } | { icon: string }。但它在 HTML 中不再起作用,因为 checkedicon 在“联合类型”级别可用,但仅适用于左或右大小写。

有没有办法在一些经过调整的 HTML 模板中使用这个模型?

【问题讨论】:

    标签: angular typescript


    【解决方案1】:

    有点晚了,但我现在也有类似的问题。如果找到了解决方案,但它不是很优雅。我希望有更好的东西... 您可以像这样将您的项目包装在 $any() 运算符中:

    <input type="checkbox" [(ngModel)]="$any(item).checked" *ngIf="!item.icon">
    <i class="{{$any(item).icon}}" *ngIf="item.icon">
    

    应该可以的。

    【讨论】:

    • 我不知道 $any() ? 作为最后的手段有用(如 TypeScript 中的 as any)。就我而言,不得不多次使用它让我很困扰。但它给了我使用函数让编译器开心的想法 - 请参阅 stackoverflow.com/a/67516737/8634147 :好一点,但仍然不完美?
    • 是的,这稍微干净一些,但仍然是 hack。也许有人在某个时候提出了更好的解决方案。从我的角度来看,这是一个非常常见的用例:您想要显示一个类型不同的项目列表,并根据类型显示不同的东西。应该有可能以适当的方式处理这个问题。
    【解决方案2】:

    这不是我期望的解决方案,而是一个调整

    我们可以使用 union 类型键入我们的 item 并仍然在 HTML 模板中使用它,但通过一个 tweak 函数调整类型以使 2 个内部类型相互兼容。因此,我们的想法是在 HTML 模板中使用“调整项”,而在 TypeScript 代码的其余部分中仍然使用常规项。

    这里是 TypeScript 中的演示代码,props 模拟了 HTML 模板中的用法:

    type Item =
      | { checked: boolean }
      | { icon: string };
    
    const items: Item[] = [{ checked: true }, { icon: 'checked' }];
    
    const propsKo = items.map(x => ({ checked: x.checked, icon: x.icon }));
    //                                           ~~~~~~~          ~~~~
    // ? Property 'xxx' (icon/checked) does not exist on type 'Item'
    
    
    // ? Tweak
    type ItemTweaked =
      | { checked: boolean; icon: never }
      | { icon: string; checked: never };
    
    const tweak = (item: Item) => item as ItemTweaked;
    
    const propsOk = items.map(tweak).map(x => ({ checked: x.checked, icon: x.icon }));
    //                        ^^^^^
    

    【讨论】:

      猜你喜欢
      • 2019-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-25
      • 1970-01-01
      • 2017-08-28
      • 1970-01-01
      • 2020-12-05
      相关资源
      最近更新 更多