2

我正在尝试向主干添加一些功能,以便我可以与 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 函数中放入它很难看,无论如何在创建后自动实现这一点?

4

2 回答 2

5

所以我已经考虑这个问题几天了,我想出的最干净的东西是这样的:

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.Events,在我们的情况下,Backbone.Model)。

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

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

这是一个小提琴,它通过一些额外的日志记录等来证明这一点。

于 2012-07-06T13:44:28.173 回答
1

我正在开发一个相当大的代码库,视图中有 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 函数被继承)

于 2014-02-21T21:54:26.830 回答