动态定义猫鼬模型方法
Defining mongoose Model Methods Dynamically
我在一个函数的情况下,能够根据不同的情况搜索不同的字段。
它返回相同的数据集,它只是通过不同的字段搜索:userId或tagId。因此,在我的代码中,我有这样的东西:
var findByMethod;
if (searchBy === 'userId') {
findByMethod = UserArticleModel.findByUser;
}
else {
findByMethod = UserArticleModel.findByTag;
}
findByMethod(idToSearch, function (err, articles) {…});
findByUser
和findByTag
是在UserArticleModel.js
UserArticleModel.js
var mongoose = require('mongoose');
var userArticleSchema = new mongoose.Schema({
…
}
});
userArticleSchema.statics.findByUser = function (userId, callback) {
this.find({userId: userId}, function () {…});
};
userArticleSchema.statics.findByTag = function (tagId, callback) {…};
module.exports = mongoose.model('UserArticle', userArticleSchema);
回到控制器,当我这样做时:
UserArticleModel.findByTag(idToSearch, function (err, articles) {…});
一切都很好,一切顺利。但是当我通过变量:
动态调用方法时findByMethod(idToSearch, function (err, articles) {…});
节点返回错误:
DOMAINE ERROR CAUGHT: TypeError: Object #<Object> has no method 'find'
我怀疑this
不被绑定到正确的范围,但我真的不明白为什么作为findByMethod === UserArticleModel.findByUser // true
我认为你把它弄得更复杂了。虽然这是一个很容易落入的陷阱,"过于逐字逐句"地遵循文档中的API示例,并基本上认为"这就是我需要硬编码的方式,因为文档说这是你应该做的"
JavaScript对象是"对象",因此只是分配"命名"静态方法,这实际上只是对象属性,只是一个基本的过程,从已经定义的"对象"中"循环"定义的"模式路径",并为"findByFieldName"方法设置属性。
它只是"分配命名属性",没有比这更晦涩、更复杂、甚至更"简洁"的了。
如果"听起来有点拗口",那么在整个对象结构中迭代对象属性和"设置其他属性"的实际过程并不像您想象的那么难。
举个简单的例子:
var async = require('async'),
pascal = require('to-pascal-case'),
mongoose = require('mongoose'),
Schema = mongoose.Schema;
var testSchema = new Schema({
fieldA: String,
fieldB: Number
});
function setStatics(schema) {
Object.keys(schema.paths).filter(function(key) {
return key != '_id';
}).forEach(function(key) {
schema.statics['findBy' + pascal(key)] = function(arg,callback) {
var query = {};
query[key] = arg;
this.findOne(query,callback);
};
});
};
// Set up findByFieldName other than _id
setStatics(testSchema);
var Test = mongoose.model( 'Test', testSchema, "test" );
mongoose.connect('mongodb://localhost/test');
async.series(
[
function(callback) {
Test.remove({},callback);
},
function(callback) {
Test.create([
{ "fieldA": "a", "fieldB": 1 },
{ "fieldA": "b", "fieldB": 2 }
],callback);
},
function(callback) {
Test.findByFieldA("a",function(err,doc) {
console.log(doc);
callback(err);
});
},
function(callback) {
Test.findByFieldB(2,function(err,doc) {
console.log(doc);
callback(err);
});
}
],
function(err) {
if (err) throw err;
mongoose.disconnect();
}
);
通过输出"测试它们"来证明它们是有效的:
{ _id: 55f2ae1b7d8315f40b1a2b77, fieldA: 'a', fieldB: 1, __v: 0 }
{ _id: 55f2ae1b7d8315f40b1a2b78, fieldA: 'b', fieldB: 2, __v: 0 }
这就是它的全部。
当然,对于像"Arrays"这样的字段,您希望更多地参与其中,但这是作为一个列表的基本前提,您可以自己尝试(或一般社区的自我)。
我还可以注意到已经有一些东西了,比如Bluebird通过它自己的.promisifyAll()
调用与对象交互,以类似的方式在对象上设置新的"命名方法"。或者至少在原则上应该是相似的,因为我实际上并没有看过那段代码。
- 有没有比在app.js上绑定模块名称更好的方法来动态加载视图模型和视图以显示模态
- sails.js beforeCreate方法只接收required设置为true的模型属性
- 在extJS 4.2中,有没有一种方法可以将模型值动态绑定到表单
- 有没有一种方法可以在设计模式下将ng模型或工厂绑定到iframe
- Odoo销售点如何访问模型并使用JS调用方法
- 有没有一种方法可以使用angular中的$index作为ng重复中的模型
- Ember.js-模型find()方法中的异步调用
- Django 使用 JSON 获取模型方法的值
- 如何将经度/经度值绑定到挖空视图模型方法
- 主干模型方法未递增
- 从父级转换时,不会触发 Ember 子路由模型方法
- 主干.js - 模型方法中“this”的范围
- 用javascript调用模型方法
- Angular2服务调用模型方法
- 如何覆盖现有的骨干模型方法,保持其他方法相同
- Backbone model.get()在模型方法中未定义
- 动态定义猫鼬模型方法
- 尝试导航时模型方法错误
- SailsJS覆盖模型方法
- 如何在blueprint api中显示模型方法