【问题标题】:Adding more functions to Backbone Models向主干模型添加更多功能
【发布时间】:2014-02-22 06:09:20
【问题描述】:

我正在尝试向主干添加一些功能,以便可以与 mongodb 进行通信。现在我知道这在客户端不起作用;但是,我也喜欢主干的服务器端模型逻辑功能。我注意到,如果我继续为每个模型添加相同的功能,我会做大量重复工作,因此我决定在服务器端创建一个“app_model”文件来扩展主干。我也不想覆盖标准的 Backbone 函数,因为它们将是有用的客户端。

让我们以这个用户类为例:

var Backbone = require('./app_model');

var User = Backbone.Model.extend({
    name : "users",
    defaults: function() {
        return {
            username: "default",
            role: 2,
            created: new Date(),
            updated: new Date(),
            logged: new Date()
        };
    },
    idAttribute: "username",
    /**
     * A predefined listing of user roles
     */
    userRoles: [
        "admin",  //0
        "author", //1
        "user"    //2
    ],
    initialize: function() {
        if(!!app) {
           this.svrInit();
        }
    }
});

module.exports = User;

我想通过使用我的“app_model.js”文件将函数附加到主干上,该文件目前看起来像这样:

var Backbone = require('backbone'),
  Deferred = require('Deferred'),
  when = Deferred.when;

Backbone.Model.prototype.svrInit = function() {
    //TODO: perhaps the code below should be made static some how so we don't have a bunch of instances of collection
    var model = this;
    if(!!app.db){
        app.db.collection(this.name,function(err,collection){
            model.collection = collection;
        });
    }
};

Backbone.Model.prototype.svrSave = function() {
    var model = this.toJSON();
    var dfd = new Deferred();
    this.collection.insert(model, {safe:true}, function(err, result){
        dfd.resolve();
    });
    return dfd;
};

Backbone.Model.prototype.svrFind = function(options) {
    var model = this.toJSON();
    var dfd = new Deferred();
    this.collection.find(options, {safe:true}, function(err, result){
        dfd.resolve();
    });
    return dfd;
};

module.exports = Backbone;

当我把它抽象出来时,我运行了我的测试,它似乎工作正常。有没有更好的方法来做到这一点?有坑掉吗?我正在使用全局“app”变量,这很糟糕吗?如果是这样,有什么方法可以解决它?我确实觉得我不得不将 this.svrInit() 放在模型级别的 init 函数中很难看,无论如何在创建后自动实现这一点?

【问题讨论】:

    标签: javascript node.js backbone.js


    【解决方案1】:

    所以我这几天一直在思考这个问题,我想出的最干净的东西是这样的:

    var MyModel = function( attributes, options ) {
      Backbone.Model.apply( this, arguments );
      this.specialInitializer();
    };
    
    MyModel.extend = Backbone.Model.extend;
    
    _.extend( MyModel.prototype, Backbone.Model.prototype, {
      specialInitializer: function() {
        // called after the users 'initialize'
        console.log("MyModel initialized.", this);
      },
      otherNewMethod: function() {
        // this is just like any other instance method,
        // just as if Backbone.Model implemented it
      }
    } );
    

    所以这基本上是创建一个全新的“类型”Backbone.Model。一个也叫specialInitializer。如果您在 Backbone.Model 的构造函数定义之后查看 backbone source,您会发现这是一个类似的策略。

    • 构造实例。
    • 调用实现者应该定义的初始化器。
    • 使用功能扩展原型(在他们的情况下为Backbone.Events,在我们的情况下为Backbone.Model)。

    您的新初始化程序当然可以调用它需要的任何其他内容,等等。

    至于您关于静态集合内容和全局应用程序变量的其他问题,恐怕我没有完全了解那里发生了什么,因为我没有看到 app 的定义并且不知道您将集合用于什么目的。

    这是a fiddle,它通过一些额外的日志记录等来证明这一点。

    【讨论】:

    • 啊,我明白了!我见过一些类似的概念,但不确定它是如何实现的。我的部分问题是关于 Node.JS。我有一个 server.js 文件,它使用 expressjs 定义了一个变量应用程序。它是一个全局的,可以通过我的应用程序的服务器端部分访问。我见过的所有例子都是这样做的。我想我可以将其视为“窗口”或“文档”;但是,我创建了一个数据库连接并将其也放入 app 变量中。否则我会为每个模型创建新的数据库连接。我想这是有道理的。但是,不鼓励使用全局变量...
    • app.db.collection 是应用程序全局变量。 db 是 mongodb 的 NodeJS 库的一部分。 collection 指的是一个 mongodb 集合。如果您不了解集合,它们基本上就像表格。所以我正在对它们执行查找和插入操作。
    • 我也喜欢调用初始化函数的解决方案!感谢您的帮助!
    • 我对 MongoDB 和 Node 很熟悉,但我肯定遗漏了一些东西。您在服务器端使用 Backbone 吗?如果是这样,我认为可以像您一样使用全局变量。
    • 是的,我正在使用骨干服务器端并尝试重用相同的类客户端。我想我将使用 requirejs 客户端并在那里使用不同的 MyModel 类。这样我就可以保持大部分模型逻辑完好无损,包括验证等。我什至可以做一些事情,比如使用 jQuery 中的 Deferred,而不是我目前使用的服务器端的其他库。
    【解决方案2】:

    我正在处理一个相当大的代码库,视图中有 4-5 级继承。这是我正在使用的模式:

    var BaseView = Backbone.Model.extend({
      somefunc: function() {
        //contents
      },
    
      otherfunc: function(a,b,c) {
        //contents
      },
      //...
    });
    
    
    var User = BaseView.extend({
      // things in user view can now access somefunc and otherfunc
    });
    

    这是jsfiddle 中的一个简单示例(注意 doSearch 函数被继承)

    【讨论】:

    • 是的,我们最近在一定程度上使用了这种模式。我们注意到 4->5 级的继承给我们带来了很多麻烦。我们认为混合模式与一些有限的继承结合起来非常有用。我们使用:github.com/rhysbrettbowen/Backbone.Advice
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-25
    • 1970-01-01
    • 1970-01-01
    • 2015-09-05
    • 2013-10-11
    • 2011-05-09
    • 1970-01-01
    相关资源
    最近更新 更多