是否可以从 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">
无论如何,希望对您有所帮助。祝你好运!
我创建了一个枚举,目前它是键和值动态,但现在它需要来自服务作为显示文本的值,但我还是找不到如何做到这一点。 我只需要从服务中获得的价值,而不是改变动态,这将只是一个带有文本的价值 这是枚举。
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">
无论如何,希望对您有所帮助。祝你好运!