账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    前端对请求数据做预处理/格式化的方式。
    • 2019-12-15 00:00
    • 10
    40
    0

    问题描述

    在与后台交互的过程中遇到的关于处理数据格式的问题。

    问题出现的环境背景及自己尝试过哪些方法

    比如:后台传过来一个list,格式如下

    list: [
      {
        id: 10086,
        firstName: '小',
        lastName: '明',
        birth: 1546072820279,
        age: 11,
        sex: 0,
        // 其他属性
        ...
      },
      ...
    ]

    然后,我想对数据做预处理,原因有下面两点:

    1. 渲染在页面上之前,需要先对data中的某些项做数据处理。
    2. 防止后端同学修改了字段,如id -> userId,如果不统一在model层做处理,那后期维护就很麻烦,需要在页面中一个个找id,然后换成userId

    我的想法是单独创建一个model.js用于统一处理这些数据预处理。

    方法1: 类

    // model.js
    class Person{
      constructor(props){
        // 将原始data的所有的属性做挂载   Question1: 此处印象中应有更方便的写法用于挂载所有属性 Object.create(props)?
        Object.keys(props).forEach(prop => {
          this[prop] = props[prop];
        });
        // 将需要处理的数据进行处理/重写
        this.name = props.firstName + props.lastName;
        this.birthDate = new Date(props.birth);
        // 假设0为男 1为女
        this.sex = props.sex === 0 ? '男' : '女'
      }
      // 后期如需扩展,可以写一些原型方法
      // 如通过id请求手机号
      getPhone(){
        fetch(xxx, { id: this.id }).then(...)
      }
    }
    
    // 最终我们就可以直接在页面/业务组件中直接渲染format之后的list
    export const formatList = list => list.map(item => new Person(item));

    方法2: 代理

    // model.js
    const personHandler = {
      get(target, property){
        switch (property) {
          case 'name':
            return target.firstName + target.lastName;
          case 'birthDate':
            return new Date(target.birth);
          case 'sex':
            return target.sex === 0 ? '男' : '女';
          // 其他属性直接返回,相比于方法1,省去了遍历挂载的过程。 
          // Question 2 但是这里如何给target添加原型方法呢?总不能直接target.getPhone = function(){...}吧? 那岂不是每个target都挂载了一个方法,没有必要。 
          default: return target[property];
        }
      }
    };
    
    export const formatList = list => list.map(item => new Proxy(item, personHandler));
    

    结论

    对于原因1: 我们将这些数据的预处理(与业务逻辑无关),从业务组件/逻辑中抽离出来,让业务组件/逻辑更加纯粹地处理业务。
    对于原因2: 如果后端同学说将id改为userId,我只需要在class 或 proxy中加一行代码就搞定了
    方法1中: this.id = props.userId ,方法2中:case 'id': return target.userId

    问题: 注释中的 question1 和 2.
    question3: 方法1和方法2哪个更适合处理这种场景呢。 求大佬们帮忙对比分析下。

    回顾
    目前在处理业务需求中这种场景的时候,会在tools.js里增加一个对应的formatXXXData(XXX) { // 将XXX map 处理,然后return处理后的值}的函数。 感觉这种做法不太直观,所以在考虑是否应该增加一个model.js文件,用上面类似于 class Person的形式来处理这些数据格式化和某些业务逻辑(比如getPhone())的问题。
    但是这样会不会增加内存开销呢?毕竟需要将后端返回的dataList全部实例化, 设置了许多属性和方法。。

    0
    打赏
    收藏
    点击回答
    您的回答被采纳后将获得:提问者悬赏的 10 元积分
        全部回答
    • 共 0 条
    • 少酒惊砚 普通会员 1楼
      502 Bad Gateway

      502 Bad Gateway


      nginx
    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部