前端-如何将两个不同的字段mapping到一个字段?

由于产品系统升级,假设是由A系统升级为B系统,现在拿同一个产品详情信息,A系统和B系统的信息一模一样,不同的所有信息两个系统给前端的字段名称不一样,然而我在显示产品详细信息的时候我不想A || B这样显示不同系统的信息,因B升级完全完成测试没有问题后A终将淘汰,有什么比较优雅的方法解决这个问题吗?
我是前端开发,应用的框架为angular14

接口返回后立马转换这个方案行不通,因为我后面拿产品下单需要将整个product信息传给后端,A系统需要A系统的数据,B系统需要B系统的数据结构,单独定义一个常量用于HTML的显示也不合适,因为产品显示的地方非常多,很多是嵌套在cart对象里面的,我们是电商系统产品信息跟下单流程息息相关。

阅读 2.8k
3 个回答

没明白你想干什么。如果一个数据,分别从 A 和 B 去拿,那就可能拿到 1 个或者 2 个数据。如果只拿到一个就好办,用它就行。如果拿到两个,在这两个数据中,一定要做出一个选择

  • 要么优先选 A:A ?? B
  • 要么优先选 B:B ?? A
  • 要么合并,也存在优先顺序:{ ...A, ...B }{ ...B, ...A }

如果 A 和 B 的部分属性名称不一样,可以理解为接口不一样(获取属性的接口)。解决接口不一样可以使用适配器。比如

A 是 { product_name: "", product_price: 11 } 这样的
B 是 { productName: "", productPrice: 11 } 这样的

以 B 为标准,给 A 写适配器

class AdapterA {
    #origin;
    constructor(origin) {
        this.#origin = origin;
    }

    get productName() { return this.#origin.product_name; }
    get productPrice() { return this.#origin.product_price; }
}

然后写一个适配函数,根据你的开关来选用其中一个。比如

function wrapA(a) {
    return new AdapterA(a);
}

function wrapB(b) {
    return b;
}

// ...
const wrap = options.B ? wrapB : wrapA;

当然,如果属性名称变化比较有规律,可以使用 Proxy 来代替 Adapter,也可以直接在 wrap 函数进对对象进行转换处理,比如从下划线方式转为 camel(用 Lodash,或者 name-styles - npm (npmjs.com))

import { camel } from "name-styles";

function wrapA(a) {
    return Object.fromEntries(
        Object.entries()
            .map(([key, value]) => [camel(key), value])
    );
}

属性名如果没有特别的规律,也可以建名称映射表来处理。就写在对 A 的适合处理代码文件中,毕竟这个文件以后是要拿掉的。举例:

nameMap = {
    "product_name": "standardizedName"
}

function wrapA(a) {
    return Object.fromEntries(
        Object.entries()
            .map(([key, value]) => [nameMap[key] ?? key, value])
    );
}

可以在拿到接口返回数据做转换,比如你定义业务使用C类型数据结构,可以A转C,B转C这样不太影响

这样试一下看看行不行,还是需要拿到数据立即进行转一层

const dataA = transform(A)
const dataB = transform(B)

const systemInfo = {
    // 页面展示信息从 转换后的数据取
    ...dataA,
    ...dataB,
    // 回传给 api 的多加两个冗余字段保存
    originalA: A,
    originalB: B,
    
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题