ES6:使用 class 作为模块

ES6: Using a class as a module

我正在使用存储库模式、nodejs、graphql 和 sequelize 编写一个简单的应用程序。首先是我的基本存储库:

import db from '../models';

export default class AbstractRepository {
  constructor (model, include) {
    if (new.target === AbstractRepository) {
      throw new TypeError('Cannot construct AbstractRepository instances directly.');
    }
    this.model = model;
    this.include = include;
  }
  static findAll () {
    return db[this.model].findAll({ include: this.include });
  }
}

这是一个扩展它的存储库:

import db from '../models';
import AbstractRepository from './AbstractRepository';

class UserRepository extends AbstractRepository {
  constructor () {
    super('User', [db.Clickwrap]);
  }
}

export default new UserRepository();

最后,这里是使用 UserRespository 的地方(这个文件还有更多内容,但这是重要的部分):

import UserRepository from '../../repositories/UserRepository';

const resolvers = {
  Query: {
    users (root, args, context) {
      return UserRepository.findAll();
    },
  },
};

当我 运行 像这样在 graphiql 中进行简单的 graphql 查询时:

{
  users {
    id
  }
}

我收到这个错误:

_UserRepository2.default.findAll is not a function

不确定是我遗漏了什么导致的。

编辑

我更新了我的代码,因此它不再导出实例。其他一切都保持不变。这是我的新 UserRepository 文件:

import db from '../models';
import AbstractRepository from './AbstractRepository';

class UserRepository extends AbstractRepository {
  constructor () {
    super('User', [db.Clickwrap]);
  }
}

export default UserRepository;

现在我收到这个错误:

Cannot read property 'findAll' of undefined

静态函数不可在 class 的实例上调用。请参阅 MDN documentation on static 上的最后一个示例。

在您的代码中,您正在导出 UserRepository:

的一个实例
export default new UserRepository();

您稍后使用与 class 名称相同的名称导入:

import UserRepository from '../../repositories/UserRepository';

现在,当您执行 UserRepository.findAll() 时,您是在 UserRepository class 的实例上调用 findAll 函数。您导入了与 class 同名的实例。您实际上并没有在 class 上调用静态函数 findAll。相反,您是在实例上执行此操作。

正如 Bergi 已经建议的那样,只需导出 class:

export default UserRepository;

正如我在上面的评论中提到的,我的做法是错误的。一旦我按照建议做了并导出了 class 而不是 class 的实例,我得到了一个未定义的错误,我认为这意味着 UserRepository 没有在我的 user.js 文件中定义.然而,错误实际上是在我的 AbstractRepository 中的 findAll() 方法中,因为 this.model 从未设置过,因为我试图用静态来做所有事情,因此从不调用构造函数。所以我放弃了静态废话,实例化了我的UserRepository的一个实例。所以 UserRepository 看起来就像我原来的 post 的编辑部分一样。但是 AbstractRepository 现在看起来像这样:

import db from '../models';

export default class AbstractRepository {
  constructor (model, include) {
    if (new.target === AbstractRepository) {
      throw new TypeError('Cannot construct AbstractRepository instances directly.');
    }
    this.model = model;
    this.include = include;
  }
  findAll () {
    return db[this.model].findAll({ include: this.include });
  }
}

我的 user.js 文件如下所示:

import UserRepository from '../../repositories/UserRepository';

const userRepo = new UserRepository();
const resolvers = {
  Query: {
    users (root, args, context) {
      return userRepo.findAll();
    },
  },
};

现在一切正常。谢谢大家指引我正确的方向。