先说明,官方文档中这种get方法的示例是完全没问题的
module.exports = class extends think.Model { // 配置关联关系 get relation() { return { cate: { // 配置跟分类的关联关系 type: think.Model.MANY_TO_MANY, ... }, comment: { // 配置跟评论的关联关系 } } }}复制代码
因为get方法相当于是直接挂在类prototype上的取值函数,是在super()方法执行时就已经存在的了
这种构造函数里的赋值方法是有问题
// 代码1module.exports = class extends think.Model { constructor(...args){ super(...args); this.relation = { comment: think.Model.HAS_MANY, cate: think.Model.MANY_TO_MANY }; } getList2(){ return this.setRelation(true).select(); }}复制代码
代码1 是在官方文档示例中,另一种对model.relation的定义,试图在继承了think.Model的用户自定义model类的构造函数中通过this给relation赋值,从而传递到 Relation的实例中,这是做法无法实现的。
ENV
OS Platform:
win10 64复制代码
Node.js Version:
v10.13.0复制代码
ThinkJS Version:
thinkjs@3.2.10think-model@1.3.1复制代码
原因分析
翻看think-model中model.js和relation.js的代码可以发现:
// model.js 代码2constructor(modelName = '', config = {}) { if (helper.isObject(modelName)) { [modelName, config] = ['', modelName];}assert(helper.isFunction(config.handle), 'config.handle must be a function');this.config = config;this.modelName = modelName;this.options = {};this[RELATION] = new Relation(this);}复制代码
==在Model类(代码2)中,属性this[Symbol('think-model-relation')]
的实例化是在代码1中子类this.relation初始化之前完成的(毕竟要先实行super()),所以this[RELATION] = new Relation(this)
时,传入的this中,并没有自定义的relation属性。==
// relation.js 代码3 constructor(model) { this.model = model; this.relation = this.model.relation || {}; this.relationName = true; }复制代码
==继续翻看relation.js(代码3)的代码发现,如果Relation类的构造函数没有接收到有效的relation值,则会把this.relation置为一个空对象,而且由于Relation实例化是复制给了一个本地Symbol类型变量,后期在外部或者子类中也无法引用到了,所以初始化之后是无法改变的。==
另一种可行的写法 但是没什么卵用 不如用get
// 代码4class user extends think.Model { constructor(...args){ super(...args); }/* get relation() { return { auths: { type: think.Model.HAS_MANY, model: 'user_auths', fKey: 'id_user', relation: false } } }*/ async getUserByAuthTypeAndIdentifier(authType, identifier) { const auth_sql = await this.model('user_auths').setRelation(true).where({auth_type: authType, identifier: identifier}).buildSelectSql(); return this.alias('u').join({ table: auth_sql, join: 'inner', as: 'a', on: { 'id': 'id_user', } }).find(); }}user.prototype.relation = { auths: { type: think.Model.HAS_MANY, model: 'user_auths', fKey: 'id_user', relation: false }}module.exports = user复制代码
如果想不用get方法实现 我只想到了上述代码4这种写法,也就是在原型上扩展一下。