3

アプリを実行する例として、このAPIが必要だったとしましょう。

var db = new Database('db-name'); // DB connection
var todo = new Todo(db); // New "Todo" and pass it the DB ref
// I want this API:
todo.model.create('do this', function (data) {
  console.log(data);
});

私はそれを現在次のように設定しています:

function Todo (storage) {
  this.storage = storage;
};

Todo.prototype.model = {
  create: function (task, callback) {
    // The problem is "this" is Todo.model
    // I want the "super", or Todo so I can do:
    this.storage.save(task, callback);
  }
}

したがって、コメントを見ると、問題はthis「内部model.createが明らかに参照している」ということですTodo.modelが、「」を取得するために必要superです。

私が考えることができた最高のものは:

Todo.prototype.model = function () {
  var self = this;
  return {
    create: function (task, callback) {
      // The problem is "this" is Todo.model
      // I want the "super", or Todo so I can do:
      self.storage.save(task, callback);
    }
  }
}

しかし、これらはどちらも素晴らしいものではありません。model最大の問題は、すべてのメソッドを単一のオブジェクト(1番目の例)または関数(2番目)の内部に配置したくないということです。モデルdefの内側からそれらを取り出せるようにしたいと思います。次に、todo.model.createAPIが必要です。

これを実現するためのデザインパターンはありますか?

4

3 に答える 3

1

を使用するbindと、次のようなことができます。

function Todo (storage) {
  this.storage = storage;
  this.model = {};

  var methodNames = Object.keys(TodoModel);

  for(var i = 0; i < methodNames.length; ++i) {
    var methodName = methodNames[i];
    var method = TodoModel[methodNames];

    model[methodName] = method.bind(this);
  }
};

var TodoModel = {
  create: function(task, callback) {
    // Note that when this method is called using Todo.model.create,
    // 'this' will point to the Todo instance.
    this.storage.save(task, callback);
  }
};

function test(storage) {
  var todo = new Todo(storage);
  var task = {};

  todo.model.create(task, function(err, savedTask) {
    // ...
  });
}

TodoModel基本的にマップであるため、これを Map コレクションに置き換えることができ、 を呼び出す必要がなくなりますObject.keys

于 2012-10-22T09:02:02.157 に答える
1

は のプロパティtodo.modelあるため、作成したとおりに のプロトタイプ パターンを使用することはできません。modeltodo

私はあなたが必要だと思います:

  1. プロトタイプ モデルを使用できる新しいModelオブジェクト。

  2. Todoコンストラクターで、オブジェクトを作成しますModel。理想的には、読み取り専用の「getter」関数を使用して、そのモデル オブジェクトにアクセスできるようにしますが、上書きはできません。

于 2012-10-22T07:30:00.253 に答える
0

model次の例のように、コンストラクターで を設定できます。

function Todo (storage) {
  var self = this;

  this.storage = storage;

  this.model = {
    create: function(task, callback) {
      self.storage.save(task, callback);
    }
  };
};

または、 bindを使用することもできますが、古いブラウザーで動作する実装を見つける必要があり、EcmaScript 5 をサポートする新しいブラウザーのネイティブ実装と競合しないため、不必要に複雑になると思います。

于 2012-10-22T07:32:35.940 に答える