Angular 筛选对象

Angular filter object

按架构 Angular 过滤 json 供稿的最佳方法是什么?我想这样做的原因是使用传输状态 API.

减少存储在 html 页面中的数据量

理想世界我想定义一个接口,并且只使用那些字段。但是接口只在编译时使用,而不是运行时。

所以目前使用的是:

export const FieldWhitelist = {
  'slug': true,
  'title': true,
  'type': true,
};

get(url): Observable<any> {
    return this.http.get(url).pipe(
      map(items => {
        if (typeof items === 'object') {
          Object.keys(items).forEach(field => {
            if (!FieldWhitelist[field]) {
              delete items[field];
            }
          });
        } else if (typeof items === 'array') {
          Object.keys(items).forEach(item => {
            Object.keys(items[item]).forEach(field => {
              if (!FieldWhitelist[field]) {
                delete items[item][field];
              }
            });
          });
        }
        return items;
      })
    );
}

这会变成 json 供稿:

{
  'id': '12x324jh34',
  'metadata': 'sajhjksadhjkdsa'
  'slug': 'home',
  'title': 'Homepage',
  'type': 'page',
}

进入这个:

{
  'slug': 'home',
  'title': 'Homepage',
  'type': 'page',
}

是否有更好的方法递归过滤 json 供稿以匹配架构?

您可以定义一个 class 并在其中映射 items,返回 class

const obj = {
  'id': '12x324jh34',
  'metadata': 'sajhjksadhjkdsa',
  'slug': 'home',
  'title': 'Homepage',
  'type': 'page',
}; 

class Data {
  slug: string;
  title: string;
  type: string;

  constructor({slug, title, type}: {slug: string, title: string, type: string}) {
    this.slug = slug;
    this.title = title;
    this.type = type;
  }
}

console.log(new Data(obj));

还要确保知道这里的 items 是什么,你不应该需要检查它是数组还是对象恕我直言,返回部分应该清楚这一点

 map(items => {

找到另一种使用 deserialize.ts 助手 class 来执行此操作的方法,它使用 Reflect Metadata 存储属性:

import 'reflect-metadata';

const CUSTOM_PROPS = 'custom:properties';

export function Expose(target: any, key: string) {
  const properties = Reflect.getMetadata(CUSTOM_PROPS, target) || [];
  properties.push(key);
  Reflect.defineMetadata(CUSTOM_PROPS, properties, target);
}

export class Deserializable {
  deserialize(input: object): this {
    const properties = Reflect.getMetadata(CUSTOM_PROPS, this);
    properties.forEach(key => {
      this[key] = input[key];
    });
    return this;
  }
}

模型的用法:

import { Expose, Deserializable } from './deserialize';

export class Brand extends Deserializable {
  @Expose name: string;
  @Expose image: string;
  @Expose link: string;
}