Javascript ES6:将类用作模块

Javascript ES6:将类用作模块,javascript,ecmascript-6,sequelize.js,graphql,Javascript,Ecmascript 6,Sequelize.js,Graphql,我正在使用存储库模式nodejs、graphql和sequelize编写一个简单的应用程序。首先,这里是我的基本存储库: import db from '../models'; export default class AbstractRepository { constructor (model, include) { if (new.target === AbstractRepository) { throw new TypeError('Cannot constr

我正在使用存储库模式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的地方(该文件还有更多内容,但这是重要的部分):

当我在graphiql中运行一个简单的graphql查询时,如下所示:

{
  users {
    id
  }
}
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 });
  }
}
import UserRepository from '../../repositories/UserRepository';

const userRepo = new UserRepository();
const resolvers = {
  Query: {
    users (root, args, context) {
      return userRepo.findAll();
    },
  },
};
我得到这个错误:

_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

静态函数不能在类的实例上调用。请参见上的最后一个示例

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

export default new UserRepository();
稍后将以与类名相同的名称导入:

import UserRepository from '../../repositories/UserRepository';
现在,当您执行
UserRepository.findAll()
时,您正在
UserRepository
类的实例上调用
findAll
函数。您使用与类名相同的名称导入了该实例。实际上,您没有在类上调用静态函数
findAll
。而是在一个实例上进行

正如Bergi已经建议的,只需导出类:

export default UserRepository;

静态函数不能在类的实例上调用。请参见上的最后一个示例

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

export default new UserRepository();
稍后将以与类名相同的名称导入:

import UserRepository from '../../repositories/UserRepository';
现在,当您执行
UserRepository.findAll()
时,您正在
UserRepository
类的实例上调用
findAll
函数。您使用与类名相同的名称导入了该实例。实际上,您没有在类上调用静态函数
findAll
。而是在一个实例上进行

正如Bergi已经建议的,只需导出类:

export default UserRepository;

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

{
  users {
    id
  }
}
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 });
  }
}
import UserRepository from '../../repositories/UserRepository';

const userRepo = new UserRepository();
const resolvers = {
  Query: {
    users (root, args, context) {
      return userRepo.findAll();
    },
  },
};
我的user.js文件如下所示:

{
  users {
    id
  }
}
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 });
  }
}
import UserRepository from '../../repositories/UserRepository';

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

现在一切都很好。谢谢你们引导我朝着正确的方向前进。

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

{
  users {
    id
  }
}
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 });
  }
}
import UserRepository from '../../repositories/UserRepository';

const userRepo = new UserRepository();
const resolvers = {
  Query: {
    users (root, args, context) {
      return userRepo.findAll();
    },
  },
};
我的user.js文件如下所示:

{
  users {
    id
  }
}
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 });
  }
}
import UserRepository from '../../repositories/UserRepository';

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

现在一切都很好。谢谢大家引导我朝着正确的方向前进。

为什么要将
findAll
设置为静态?这就是原因。而是导出类本身。@Bergi从不说“永不”。如果需要单例,默认导出是很好的(在本例中不是这样)。这并不意味着一个类也不应该被导出为命名导出,至少是为了测试。@estus如果你想导出一个单例,你应该使用对象文字而不是
class
语法。@Bergi这在某种程度上是一个品味问题,我欣赏Occam的razor,但我认为它在这里不适用。一般来说,对于单例来说,类优于对象文本,这仅仅是因为正确的继承和(这是一个令人沮丧的事实)。不管怎样,这都是离题的,因为问题中的类看起来不需要是一个单例。为什么要将
findAll
设置为静态?这就是原因。而是导出类本身。@Bergi从不说“永不”。如果需要单例,默认导出是很好的(在本例中不是这样)。这并不意味着一个类也不应该被导出为命名导出,至少是为了测试。@estus如果你想导出一个单例,你应该使用对象文字而不是
class
语法。@Bergi这在某种程度上是一个品味问题,我欣赏Occam的razor,但我认为它在这里不适用。一般来说,对于单例来说,类优于对象文本,这仅仅是因为正确的继承和(这是一个令人沮丧的事实)。无论如何,这都是离题的,因为问题中的类看起来不需要是一个单例。这将消除错误,但
findAll()
仍然会失败。我按照Bergi的建议做了,现在,@zeroplagl说它仍然失败,只是出现了一个不同的错误。有关详细信息,请参阅上面更新的帖子。感谢到目前为止的输入。这将消除错误,但是
findAll()
仍然会失败。我按照Bergi的建议做了,现在,@zeroplagl说它仍然失败,只是有一个不同的错误。有关详细信息,请参阅上面更新的帖子。谢谢你到目前为止的投入。