在Angular 6模板语句中将字符串转换为Typescript枚举

Posted

技术标签:

【中文标题】在Angular 6模板语句中将字符串转换为Typescript枚举【英文标题】:Convert string to Typescript enum in Angular 6 template statement 【发布时间】:2019-04-18 02:33:58 【问题描述】:

我有一个带有 Angular Material select component 的简单 Angular 6 应用程序,我想双向绑定到枚举变量。为此,我需要在用于标识选项的字符串值和作为实际 Typescript 类型的枚举值之间进行转换。要将字符串转换为枚举,我总是这样做(假设 Value1 是 MyEnum 的成员):

let s: string = "Value1";
let myEnumVariable: MyEnum = MyEnum[s];

但这似乎不适用于 Angular 模板语句,例如对于以下内容:

app.component.html:

<mat-form-field>
  <mat-select placeholder="Select a value" [value]="MyEnum[myVariable]" (valueChange)="myVariable = MyEnum[$event]">
    <mat-option value="Value1">Value 1</mat-option>
    <mat-option value="Value2">Value 2</mat-option>
  </mat-select>
</mat-form-field>

app.component.ts:

import  Component  from '@angular/core';

@Component(
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
)
export class AppComponent 
  title = 'app';
  public myVariable: MyEnum = MyEnum.Value1;
  public MyEnum = MyEnum;


enum MyEnum 
  Value1,
  Value2

使用 Angular 开发服务器进行开发时一切正常。但是一旦我运行ng build --prod,就会出现这个错误:

src\app\app.component.html(2,73) 中的错误::类型“字符串”不是 可分配给类型“MyEnum”。

为什么这会出现在建筑中而不是开发中?知道如何在不使用模板语句中的显式方法调用的情况下解决此问题吗?

非常感谢!

PS 我使用的是 Typescript 2.7.2

【问题讨论】:

(change)="myVariable = $any(MyEnum[$event]);" @yurzui 这解决了它!但是 VS 代码中的 Angular 给出了一个静态检查错误 - [Angular] Unknown method '$any'。有什么办法可以去掉?如果您希望您可以将此作为答案发布,我可以将其标记为已接受:) 看起来 Angular 语言服务还不支持 $any 但 AOT 支持 angular.io/guide/aot-compiler#disabling-type-checking-using-any 这就是它在aot中不起作用的原因。 stackblitz.com/edit/angular-bpgmal?file=src/app/… AOT 将 $event 处理为 any 您可以尝试的另一个选项是(change)="myVariable = MyEnum['' + $event];" 【参考方案1】:

试试这个。

let s = 'Value1' as 'Value1';
let myEnumVariable: MyEnum = MyEnum[s];

您遇到的错误是因为 Typescript 认为 s 的类型为 string 而不是 Value1。但是枚举有明确的键Value1Value2,而不是任何字符串。因此出现错误。

为什么这会出现在建筑而不是开发中?

可能在开发过程中,您有一个文件监视器,即使出现一些错误,也可以将您的 TS 编译为 JS。我的 VSCode 中有相同的观察者。但是错误仍然存​​在,因此构建过程会引发错误。

【讨论】:

很抱歉,但这不是问题所在。如果我没有在问题中说清楚,问题在于 Angular 事件绑定中的模板语句,我试图设置枚举变量的值 嘿@scharnyw 有帮助吗?我已经更新了很多次了。 非常感谢您的回复!不幸的是,Angular 模板语句不接受 Typescript “as” 运算符。顺便说一句,在 ng serve 下调试时,从字符串到枚举的转换工作正常(我已经检查过绑定是否有效),它甚至可以与 ng build 一起使用(我已经托管了在浏览器中生成和检查的文件),但由于某种原因它不适用于 ng build --prod。在我看来,这一定是 Angular 生产构建/优化的一些相当奇怪的特性。 ng build --prod 不起作用的事实很好,因为它不应该传递类型错误。关于模板中的类型转换,这可能会有所帮助:***.com/questions/45964576/… 好的。为此,似乎别无选择,只能在 TS 中使用一种方法。非常感谢!【参考方案2】:

您的模板无法将其识别为enum,因此您只需将其分配为字符串并将其读取为enum in typescript - 我不确定这是正确的方式,但您可以试一试

每个enum 都会将值与键解析匹配,并考虑传递键并在您的enum 中获得所需的输出键似乎是number,而您正试图将其作为string 获取所以chage是这样的

enum MyEnum 
  Value1 = "Value1",
  Value2 = "Value2"

现在,当您将其读取为 MyEnum.Value1.toString() 时,它会将特定值返回为“Value1”

现在像这样读取public myVariable: string = MyEnum.Value1.toString() 传递给模板应该没有string 属性如果你想在ts 中读取它,你可以传递所需的string 以从enum 获取值

<mat-form-field>
  <mat-select placeholder="Select a value" [value]="myVariable" (valueChange)="myVariable = $event">
    <mat-option value="Value1">Value 1</mat-option>
    <mat-option value="Value2">Value 2</mat-option>
  </mat-select>
</mat-form-field>

我希望这会对您有所帮助 - 尝试在 ng build --prod 中构建您的项目并检查它是否有效 - 编码愉快!

【讨论】:

这肯定会奏效。但这是否意味着无法直接在 Angular 中绑定枚举变量? 不,它不像你可以在template 中绑定,它将适用于开发构建 - 但我在产品构建中遇到了像你这样的问题,所以我找到了一种方法来获得它:) 希望这会有所帮助你 谢谢! yurzui 在问题 cmets 中找到并解释了一个解决方案。这与 Angular AOT 处理模板语句的方式有关。

以上是关于在Angular 6模板语句中将字符串转换为Typescript枚举的主要内容,如果未能解决你的问题,请参考以下文章

在 Angular 7 中将 Json 转换为对象

在javascript中将数字转换为数组| angular7的打字稿[重复]

如何在 Angular 中将 csv 或 excel 文件转换为 sql 输入数组?

如何在freemarker模板中将字符串转换为数字

如何在 smarty 模板中将数组转换为逗号分隔的字符串?

Django:在 Django 模板引擎中将 uuid 值转换为字符串