2017-01-17 67 views
0

我正在使用存储库模式,nodejs,graphql和sequelize编写一个简单的应用程序。首先这里是我的基地仓库:ES6:将类作为模块使用

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 
+2

你为什么让'findAll'静态?这就是原因。 – loganfsmyth

+0

[永远不会'导出'一个类实例!](http://stackoverflow.com/a/39079929/1048572)改为导出类本身。 – Bergi

+0

@Bergi永远不要说永远。如果需要单身人士(在本例中不是这样),默认导出很好。这并不意味着一个类不应该被导出为命名导出,至少对于测试来说。 – estus

回答

0

正如我在评论中提到上述,我会约了错误的方式。一旦我按照建议导出并导出类而不是类的实例,我得到了一个未定义的错误,我认为UserRepository未在我的user.js文件中定义。然而,错误实际上是在我的方法AbstractRepository中,因为this.model从来没有设置过,因为我试图用静态方法做所有事情,因此从不调用构造函数。所以我放弃了静态的废话并实例化了我的UserRepository。所以UserRepository看起来像它在我的原始文章的编辑部分。然而,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(); 
    }, 
    }, 
}; 

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

2

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

在你的代码,你要导出的UserRepository一个实例:

export default new UserRepository(); 

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

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

现在,当你做UserRepository.findAll(),您在UserRepository类的实例上调用findAll函数。您使用与类名称相同的名称导入该实例。你实际上并没有在类上调用静态函数findAll。相反,你正在做一个实例。

由于BERGI已经建议,只导出类:

export default UserRepository; 
+0

这会消除错误,但findAll()将会失败。 – zeroflagL

+0

我是按照Bergi的建议和现在做的,因为@zeroflagL表示它仍然失败,只是有一个不同的错误。有关详细信息,请参阅上面更新的帖感谢迄今为止的输入。 – LoneWolfPR