我的情况是,一个函数能够根据不同的情况通过不同的字段进行搜索。
它返回相同的数据集,它只按不同的字段进行搜索: 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
发布于 2015-09-11 10:37:00
我想你让这件事变得更有必要了。尽管这是一个很容易落入“太字面”的陷阱,遵循有文档的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 }这就是它的全部。
当然,对于像“数组”这样的字段,您希望得到更多的参与,但这是一个基本的前提,您可以自己尝试(或者一般社区的自我)。
我还可以注意到,已经有一些东西存在,比如蓝鸟通过它自己的.promisifyAll()调用与对象交互,以类似的方式在对象上设置新的“命名方法”。或者至少在原则上应该是类似的,因为我还没有真正看过这段代码。
https://stackoverflow.com/questions/32519751
复制相似问题