是否可以从 Angular 中的服务获取枚举值

Is it possible to get the value of enums from a service in Angular

我创建了一个枚举,目前它是键和值动态,但现在它需要来自服务作为显示文本的值,但我还是找不到如何做到这一点。 我只需要从服务中获得的价值,而不是改变动态,这将只是一个带有文本的价值 这是枚举。

const enum Test {
Test1 = 'this is test 1',
Test2 = 'this is test 2',
Test3 = 'this is test 3',
Test4 = 'this is test 4',
}

从现在开始,文本来自另一个带有 URL 的平台,我需要在插值或 属性 绑定中显示它。

Test1 = this.textService.getText('here the id of the text'),

Service中的getText方法

public getText(key: string, isGeneralKey = false): string {
  let searchKeys: string[];
  let result: string | DisplayTextMap;

  searchKeys = key.split('.');
  result = (isGeneralKey
    ? this.generalTexts[searchKeys[0]]
    : this.texts[searchKeys[0]]) as DisplayTextMap;

  if (result && searchKeys[1]) {
    result = result[searchKeys[1]];
  }
  if (result) {
    return this.decodeUnicodeTextService.getDecodedText(result as string);
  }
  return `${key} not found`;
}

A const enum cannot have computed members at all. A numeric enum that isn't const can have computed members, but unfortunately an enum with string members cannot. I don't know if there's good documentation about this, but there's at least one open issue 关于您收到的错误消息如何具有误导性。无论如何,要点是:你不能用 enum.

来做到这一点

幸运的是,您可能真的不需要 enum。通常,您可以将 enum 替换为具有 readonly 属性初始化为您关心的值的 const 对象,如下所示:

    const asReadonly = <T>(t: T): { readonly [K in keyof T]: T[K] } => t
    const Test = asReadonly({
        Test1: this.textService.getText('here the id of the text'),
        Test2: this.textService.getText('here is a different id'),
        Test3: this.textService.getText('you get the idea'),
        Test4: this.textService.getText('etc')
    });

(请注意,上面的 asReadonly() 仅在编译时使属性只读。如果您还希望在运行时只读,则可以使用 return Object.freeze(t) 而不是 t.)

然后您可以像使用 enum 值一样使用 Test 的属性:

const someVal = Test.Test2; // string

const 对象和 enum 对象之间存在一些差异,但它们可能对您的用例无关紧要。如果他们这样做,您可能可以解决这些问题。

例如:enum 引入命名的 类型 以及命名的值。但是,由于您的值是计算出来的,所以没有比使用 string 作为类型更好的了。如果你想防止有人将随机 string 值复制到你期望枚举的地方,你可以使用 branded primitive 类型:

const asEnum = <T, N extends string>(t: T, n: N) =>
    Object.freeze(t) as { readonly [K in keyof T]: T[K] & { __brand: N } };

const Test = asEnum({
    Test1: this.textService.getText('here the id of the text'),
    Test2: this.textService.getText('here is a different id'),
    Test3: this.textService.getText('you get the idea'),
    Test4: this.textService.getText('etc')
}, "Test");
type Test = typeof Test[keyof typeof Test];

然后您可以将 Test 用作具有属性的值和类型:

function acceptTestEnumOnly(t: Test) { }
acceptTestEnumOnly(Test.Test3); // okay
acceptTestEnumOnly("oops"); // error!  "oops" is not assignable to Brand<"Test">

无论如何,希望对您有所帮助。祝你好运!

Link to code