【问题标题】:API request: better approach to set a Enum valueAPI 请求:设置枚举值的更好方法
【发布时间】:2019-08-29 01:09:56
【问题描述】:

后端有一个名为 api/Options/GetEmailMessageTemplate 的端点,它返回具有此架构的对象:

{
  messageType: string, Enum: [ ConfirmationEmail, 
ConfirmationTransaction, RecoveryPassword, SetupAdminAccount, ConfirmationApiKey, ConfirmationDepositTransaction ]
  language: string, Enum: [ En, Ru, Zh, Es, Et ]
  subject: string,
  template: string,
  isUsed: boolean
}

例如回复:

{
  "messageType": 1,
  "language": "En",
  "subject": "string",
  "template": "string",
  "isUsed": true
}

这里是另一个编辑它的端点api/Options/Options/UpdateEmailMessageTemplate,它使用与上面相同的模式的 json。 messageType 可能是 Enum 中元素的编号或 Enum 值(例如 'ConfirmationEmail'

在前端列出所有数据并能够更改它我想出了这种方法:

  1. 我做了一个严格排序的数组:
messageTypes: [  
 { 
    name: 'Confirmation Email',
    success: false,
 },
...
]

如果更改此模板成功则需要成功显示

  1. 我从后端得到messageType作为一个数字ID,我只是将它用作我的数组中的索引(因此,为了使其工作,我的数组必须以完全相同的方式排序该字段的枚举),到获取该messageType 的名称并使用success 字段进行操作

3.api/Options/Options/UpdateEmailMessageTemplate 使用当前正在编辑的元素的索引获取messageType (indexOf)

虽然这种方法按预期工作,但我不禁想到有更好的方法来处理这个问题。

我想知道是否有更好的做法来处理这个问题

【问题讨论】:

  • 所以您只是想将返回从数字转换为枚举字符串,反之亦然?
  • @mwilson 我试图将messageType 服务器返回与我需要显示的前端数组链接起来,id 作为第三个字段可能会更好,但使用严格排序的数组和indexOf 来查找一个 idex 并使用该索引作为 id 似乎更短。现在我只是想知道是否有更好的方法,不同于将 id 作为我的数组中的第三个字段
  • 还不是 100% 清楚。所以服务器返回一个属性为messageType(这是一个数字)的对象。但是,您有一个与之匹配的已知“友好值”列表,并且您希望能够看到 number messageType 的字符串翻译?
  • @mwilson 是的,几乎是我所需要的,需要设法编辑它并将其发送回服务器,因此需要设法将其翻译回messageType 号码。而且它不是完全友好的值列表,它只是 C# Enum,Enum 键和分配给该键的值可以是服务器将理解和处理的两个参数
  • 我会说前端不应该对后端那么熟悉(前端不应该知道后端等枚举的顺序)。 IMO 这将被认为是可以通过使用对象或高阶函数来处理抽象来避免的耦合示例。比喻“你不会告诉服务员‘我想要一个芝士汉堡,在 165 度的平顶烤架上每边 3.5 分钟煮熟,然后盖上盖子融化芝士和....' IE 你是从实现中抽象出来的前端应该来自后端。

标签: javascript api enums


【解决方案1】:

根据我的理解,您想要一种使用友好的值列表及其 id 的方法。一种方法是创建两个单独的classes。这将使您能够将原始响应提供给单个模型,并且您可以添加翻译 id > name 或其他方式所需的任何方法。

您可能会更喜欢并使用get/set,但我对要求仍然有些模糊。但是,这是我会采取的一种方法:

/**
 * Create a class that knows how to translate it
 * Bonus points: this could be populated via your endpoint
 * that returns your enum list so you don't have to keep
 * updating it if there's a change on the backend
 */
class MessageType {
  constructor(messageType) {
    this.id = messageType;
    const messageTypes = [
      'ConfirmationEmail',
      'ConfirmationTransaction',
      'RecoveryPassword',
      'SetupAdminAccount',
      'ConfirmationApiKey',
      'ConfirmationDepositTransaction'
    ];
    this.name = messageTypes[this.id];
  }
}

/**
 * Create a class / model for your response.
 * This will enable you to add any methods
 * needed for translating things how you need
 * them. For example, you might want a method
 * to convert your model into what the backend
 * expects.
 */
class MessageTemplate {
  constructor(response) {
    this.messageType = new MessageType(response.messageType);
    this.language = response.language;
    this.subject = response.subject;
    this.template = response.template;
    this.isUsed = response.isUsed;
  }
  getJsonPayloadForBackend() {
    const payload = { ...this };
    payload.messageType = payload.messageType.id;
    return payload;
  }
}

// Usage

const template = new MessageTemplate({
  "messageType": 2,
  "language": "En",
  "subject": "string",
  "template": "string",
  "isUsed": true
});

console.log(template);
console.log('data to send to backend', template.getJsonPayloadForBackend())

【讨论】:

  • 有趣。谢谢你,但是没有使用类有一个聪明的实现吗?另外,如果没有那些“友好的价值观”会怎样?
  • TBH,我使用相同的堆栈。后端是C#,前端是JS(其实是TS)。我喜欢让一切都与后端相匹配。因此,在您的情况下,如果后端为您提供该枚举列表,我希望在前端的 TS / JS 中实现完全相同的模型,以便在您使用的内容方面绝对零混淆.显然,让事情保持同步会带来一些痛点,但这些事情已经有了答案。我还要看看 TS 如何进行枚举以及它如何转换为 js (typescriptlang.org/docs/handbook/enums.html)
猜你喜欢
  • 1970-01-01
  • 2011-12-28
  • 2015-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-14
  • 2016-12-10
  • 1970-01-01
相关资源
最近更新 更多