首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >动态定义猫鼬模型方法

动态定义猫鼬模型方法
EN

Stack Overflow用户
提问于 2015-09-11 09:10:45
回答 1查看 474关注 0票数 1

我的情况是,一个函数能够根据不同的情况通过不同的字段进行搜索。

它返回相同的数据集,它只按不同的字段进行搜索: userId或tagId。因此,在我的代码中有这样的内容:

代码语言:javascript
运行
复制
var findByMethod;

if (searchBy === 'userId') {
    findByMethod = UserArticleModel.findByUser;
}

else {
    findByMethod = UserArticleModel.findByTag;
}

findByMethod(idToSearch, function (err, articles) {…});

findByUserfindByTag是在UserArticleModel.js中定义的静态方法。

UserArticleModel.js

代码语言:javascript
运行
复制
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);

回到我的控制器,当我这样做:

代码语言:javascript
运行
复制
UserArticleModel.findByTag(idToSearch, function (err, articles) {…});

一切都很好,一切顺利。但是,当我通过变量动态调用该方法时:

代码语言:javascript
运行
复制
findByMethod(idToSearch, function (err, articles) {…});

当节点返回一个错误时,事情会出错:

代码语言:javascript
运行
复制
DOMAINE ERROR CAUGHT: TypeError: Object #<Object> has no method 'find'

我怀疑this没有被绑定到正确的范围,但我真的不明白为什么作为findByMethod === UserArticleModel.findByUser // true

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-11 10:37:00

我想你让这件事变得更有必要了。尽管这是一个很容易落入“太字面”的陷阱,遵循有文档的API示例,并认为“这是我需要硬编码的方式,因为文档说这就是您的方法”。

JavaScript对象是“对象”,因此只分配“命名”静态方法(实际上只是对象属性),只是“循环”已经定义的“对象”中定义的“模式路径”并为"findByFieldName“方法设置属性的基本过程。

它只是“指定命名的属性”,没有什么比这更晦涩或复杂,甚至是“简洁”。

如果“听起来像一口人”,那么迭代对象属性和“设置与整个对象结构中的属性”相关的实际过程并不像您想象的那么困难。

作为一个简单的例子:

代码语言:javascript
运行
复制
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();
  }
);

它通过输出“测试它们”来证明它们的工作:

代码语言:javascript
运行
复制
{ _id: 55f2ae1b7d8315f40b1a2b77, fieldA: 'a', fieldB: 1, __v: 0 }
{ _id: 55f2ae1b7d8315f40b1a2b78, fieldA: 'b', fieldB: 2, __v: 0 }

这就是它的全部。

当然,对于像“数组”这样的字段,您希望得到更多的参与,但这是一个基本的前提,您可以自己尝试(或者一般社区的自我)。

我还可以注意到,已经有一些东西存在,比如蓝鸟通过它自己的.promisifyAll()调用与对象交互,以类似的方式在对象上设置新的“命名方法”。或者至少在原则上应该是类似的,因为我还没有真正看过这段代码。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32519751

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档