Angular 管道处理数据字典显示

521 阅读2分钟

场景

数据库某个字段存储为某个数据字典项的编码值,前端需要把数据字典项编码显示为对应的编码名称。

例:有下性别数据字典

 {
    "id": "7A304cDB-ED7B-eF10-149B-bfeEbD756FD7",
    "category": "sex",		// 数据字典分类
    "code": "0",				// 数据字典编码
    "name": "男"				// 数据字典名称
  },
  {
    "id": "DCec0902-ec5c-1dFb-CE4A-aA16CEfe3eF9",
    "category": "sex",
    "code": "1",
    "name": "女"
  },
  {
    "id": "AbeEFc8d-86B6-322C-e533-c8F5fEBA16E5",
    "category": "sex",
    "code": "2",
    "name": "未知"
  }

用户列表

{
    "id": "dC0D2FFc-7f16-bBEc-4D28-eDBCaEFABDe5",
    "name": "刘涛",
    "sex": "2"
  },
  {
    "id": "cbDA7B10-2ff4-37DF-DeC8-2c8B58F3d66C",
    "name": "宋静",
    "sex": "0"
  },
  {
    "id": "E9F8B1cE-EBEc-c0c5-E3B9-09eBf898162f",
    "name": "姚桂英",
    "sex": "0"
  },
  {
    "id": "3ddDf81a-e21B-4F18-7Cce-Df60A724ddE6",
    "name": "刘洋",
    "sex": "1"
  },
  {
    "id": "f7a0AED9-DFAE-43f9-c7cf-cE2EA28EaF53",
    "name": "郭秀英",
    "sex": "1"
  }

前端请求拿到用户应该显示男性||女性||未知,而不是0||1||2

思路

/**

 思路1: 页面硬编码对应数据项编码名称。缺点是若后台数据字典有改动前端需要做对应调整,
        要是前端多处使用同一分类数据字典需改动多处,不利维护。
 
 思路2:
        通过数据字典分类请求后台拿到分类下的所有数据字典项,然后利用管道显示对应编码名称。

 */

实现

github.com/zhongzx8080…

  • 管道dict.pipe.ts
import { Pipe, PipeTransform } from "@angular/core";
import { HttpClient } from "@angular/common/http";

// 数据字典缓存
const dictCache = {};

// 后台请求缓存(避免每次使用管道都请求后台)
const reqCache = {};

@Pipe({ name: "dict" })
export class DictPipe implements PipeTransform {
  constructor(private http: HttpClient) {}

  async transform(value: any, args?: any) {
    // 自定义数据字典缓存key
    const key = `${value}==${args}`;
    dictCache[key] = dictCache[key] || this.getDictValue(args, value);
    return dictCache[key];
  }

  getDictValue(category, code) {
    // 判断是否已经发起过请求,避免重复请求
    reqCache[category] = reqCache[category] || this.requestDictionary(category);
    let req = reqCache[category] ;
    return new Promise((resolve, reject) => {
      req.then((arr) => {
        let name = this.getName(arr, code);
        resolve(name);
      });
    });
  }

  requestDictionary(category) {
    return new Promise((resolve, reject) => {
      // 模拟请求
      this.http
        .get(`assets/mock/dictionay.json?category=${category}`)
        .subscribe((arr) => {
          let dicts = [];
          if (Array.isArray(arr)) {
            dicts = arr.filter((item) => item.category == category);
          }
          resolve(dicts);
        });
    });
  }

  getName(arr, code) {
    let result = arr
      .filter((item) => item.code == code)
      .map((item) => item.name)
      .join(",");
    return result || "";
  }
}

测试

期望结果:有几个数据字典分类请求几次

GitHub代码