繁体   English   中英

过滤ES6类的属性

[英]Filter properties from ES6 class

我有一个Dto,我想要启用服务层过滤:方法selectFields采用应返回的字段名称数组,其他属性将被删除。
什么是枚举类的属性的简短方法,以便我可以遍历它们并将过滤后的属性设置为null?
在BaseDto我负责清理假值(我在这里也需要相同的功能)。

class UserServiceDto extends BaseDto {
  constructor(userDto) {
    super();
    this.fbUserId = userDto.fbUserId;
    this.fbFirstName = userDto.fbFirstName;
    this.fbLastName = userDto.fbLastName;
    this.gender = userDto.gender;
    this.birthdate = userDto.birthdate;
    this.aboutMe = userDto.aboutMe;
    this.deviceToken = userDto.deviceToken;
    this.refreshToken = userDto.refreshToken;
    this.updatedAt = userDto.updatedAt;
    this.createdAt = userDto.createdAt;
  }

  selectFields(fields) {
    // --> what's your take? 
  }

  toJson() {
    return super.toJson();
  }
}

编辑:
服务层从存储库层接收dto,包括所有数据库字段。 ServiceLayerDto旨在过滤掉web api不需要的字段(或者不应作为安全措施公开,例如PK字段,isDeleted等)。 所以结果我会看到服务方法的结尾看起来像:

return new UserServiceDto(userDto)
  .selectFields('fbUserId', 'fbFirstName', 'fbLastName', 'birthdate', 'aboutMe', 'updatedAt', 'createdAt')
  .toJson();

返回值将是web层(控制器)发送回http客户端的普通json对象。

如果您对扩展运算符没问题,可以尝试以下方法:

class UserServiceDto {
  constructor() {
    this.a = 1;
    this.b = 2;
    this.c = 3;
  }
  selectFields(...fields) {
    const result = {};
    fields.forEach(key => result[key] = this[key]);
    return result;
  }
}

new UserServiceDto().selectFields('a', 'c'); // {a: 1, c: 3}

期待super.toJson()调用,我认为由于我的selectFields()调用的结果不会是UserServiceDto类的实例,它将无法工作。 从这一点来看,有一些可能的方法我看到:

  • selectFields()体内实例化新的UserServiceDto对象,删除...fields数组中列出的所有字段(javascript delete is okey)并返回它;
  • 使用UserServiceDto构造函数params来保存selectFields()上的正逻辑,并仅传递给需要设置的props的构造函数; 在这种情况下,实例化临时对象不需要删除属性;
  • 更改toJson方法的签名,或者更好地添加一个新签名,这将允许传递fields数组,然后将当前selectFields逻辑放在toJson方法中(并删除selectFields方法): new UserServiceDto().toJson('a', 'c') ......

纯粹为了信息,我最终改变了我的应用程序架构。

存储库将Dto返回到服务层(dto直接从sql查询映射)。
该服务基于Dto构建静态视图并将其返回到Web层(由普通json对象表示)。

在我的目录结构中,我有:

- service
-- views
--- index.js
--- UserInfo.js

视图是一个简单的过滤器。 例如UserInfoView:

exports.build = ({ fbUserId, fbFirstName, fbLastName, gender, birthdate, aboutMe, updatedAt, createdAt }) => {
  return {
    fbUserId,
    fbFirstName,
    fbLastName,
    gender,
    birthdate,
    aboutMe,
    updatedAt,
    createdAt,
  };
};

使用该视图,例如服务中的UserInfoView如下所示:

const Views = require('../service/views');

exports.findActiveByUserId = async (pUserId) => {
  const userDto = await UserRepository.findActiveByUserId(pUserId);
  if (!userDto) {
    throw new ServiceError(Err.USER_NOT_FOUND, Err.USER_NOT_FOUND_MSG);
  }
  return Views.UserInfo.build(userDto.toJson());
};

我认为与我最初对这个问题的看法相比,这更具描述性。 此外,它使数据对象保持平原(无需其他方法)。
遗憾的是,我不能要求在Web层中接收类型(View),我可能稍后可以使用Typescript解决该问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM