创建一个只有一个计算属性作为键的类是否有意义,以便我可以处理JSON响应?
我有以下问题,我想创建一篇博文。创建一个有3种不同的选项。
根据博文的不同,应该有不同的模板。
现在我希望有一个主视图,我可以方便地编辑所有帖子。
JSON就是这样的:
[
{
"B1": {
"A": {
"Headline": "Hello World",
"Text": "This is a hello world text"
},
"B": {
"Headline": "Hallo Welt",
"Text": "Ein Hallo Welt Text"
},
"C": {
"Headline": "Bonjour Monde",
"Text": "Le monde est à toi."
}
}
}
]
B1是唯一的博客帖子标识符。应将A,B,C视为模板键。如果“A”则表示我们想要使用模板A.
现在对于实际问题,我想使用TypeScript及其功能。
BlogPostIdObject类是否有意义?我只创建它以便有一种简单的方法将传入的JSON解析为具有特定形状的对象。
export class RootObject {
blogposts: BlogPostIdObject[]
}
export class BlogPostIdObject {
[templateIdObject: string]: TemplateIdObject
}
export class TemplateIdObject {
Headline: string;
Text: string;
}
答案 0 :(得分:1)
在下文中,我将您的JSON样式对象文字分配给名为json
的常量:
const json = [
{
"B1": {
"A": {
"Headline": "Hello World",
"Text": "This is a hello world text"
},
"B": {
"Headline": "Hallo Welt",
"Text": "Ein Hallo Welt Text"
},
"C": {
"Headline": "Bonjour Monde",
"Text": "Le monde est à toi."
}
}
}
];
您的类型定义存在一些问题。首先,假设您只想将JSON样式的对象分配给RootObject
类型的变量,则不应使用class
。您可以通过调用其构造函数来创建类的实例,如new RootObject()
;你不能只为它分配/转换一个对象文字。 TypeScript可以让你这样做,但你可能会在运行时遇到问题。相反,使用interface
或type
,它们将接受对象文字。所以我们切换到interface
:
export interface RootObject {
blogposts: BlogPostIdObject[]
}
export interface BlogPostIdObject {
[templateIdObject: string]: TemplateIdObject
}
export interface TemplateIdObject {
Headline: string;
Text: string;
}
好的,我们来试试吧!
const interpretedJson: RootObject = json; // error!
哦,它抱怨json
不包含名为blogposts
的属性。它没有。实际上,您希望RootObject
只是 一个BlogPostIdObject[]
的数组,而不是拥有一个数组:
// note, changed to type alias instead of interface
export type RootObject = BlogPostIdObject[];
export interface BlogPostIdObject {
[templateIdObject: string]: TemplateIdObject
}
export interface TemplateIdObject {
Headline: string;
Text: string;
}
让我们再试一次!
const interpretedJson: RootObject = json; // error!
现在抱怨json[0].B1
与TemplateIdObject
不匹配。它没有,因为TemplateIdObject
实际上根本没有模板ID;它只有Headline
和Text
属性。实际上,您希望TemplateIdObject
拥有其键是某些字符串且其值具有Headline
和Text
属性的属性。让我们通过将TemplateIdObject
拆分为键和值(我将其称为TemplateValuesObject
)来解决问题:
export type RootObject = BlogPostIdObject[];
export interface BlogPostIdObject {
[blogIdKey: string]: TemplateIdObject
}
export interface TemplateIdObject {
[templateIdKey: string]: TemplateValuesObject
}
export interface TemplateValuesObject {
Headline: string;
Text: string;
}
const interpretedJson: RootObject = json; // okay
所以,现在它有效。万岁,我们都做完了,对吧?
嗯,我不知道。该定义不是很严格。它会让您发布包含许多ID的博文,例如[{"B1": {...}, "B2": {...}, ...}]
或零ID,例如[{}]
。这样可以吗?如果没有,可能JSON结构本身并不好,因为JSON对象不是为了保存未知名称的单个属性而设计的。您应该考虑将JSON更改为更像[{"blogId":"B1", "templates":{"A"...}}]
,以便数组中的每篇博文都只有一个blogId
和一组templates
。
它会让您拥有包含许多ID的模板,例如[{"B1":{"A": {...}, "B": {...}, "C": {...}, "D": {...}, ...}}]
或没有ID,例如[{"B1": {}}]
。这样可以吗?如果不是,那么它们应该是"A"
,"B"
还是"C"
?如果是这样,您可以通过将TemplateIdObject
更改为具有这些确切键来指定。
因此,如果您已完成或需要对类型定义或可能的JSON结构本身进行更多修订,则由您决定。希望有所帮助;祝你好运!