2

mongodb と通信できるように、バックボーンにいくつかの機能を追加しようとしています。これで、クライアント側では機能しないことがわかりました。ただし、サーバー側のモデル ロジックに対するバックボーンの機能も気に入っています。各モデルに同じ機能を追加し続けると、何度も作業を繰り返すことになることに気付き、サーバー側でバックボーンを拡張するために「app_model」ファイルを作成することにしました。また、標準のバックボーン関数はクライアント側で役立つため、オーバーライドしたくありません。

たとえば、次のユーザー クラスを見てみましょう。

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ず、何を使用しているのかわからないため、そこで何が起こっているのか正確にはわかりません。のためのコレクション。

これは、追加のロギングなどを使用してこれを示すフィドルです。

于 2012-07-06T13:44:28.173 に答える