私は今まで主にJavaプロジェクトに取り組んでおり、Javascriptとモジュール化について頭を悩ませようとしています。私は Java で頻繁に使用される Observer パターンが本当に好きなので、モデル モジュールの変更をリッスンするために使用できる Pub/Sub モジュールを実装しました。
テスト アプリケーションのコンポーネントは次のとおりです。
TestModel.js
define("testModel", ["observable"],
function (observable) {
var TestModel = (function () {
function TestModel() {
this.name = "name";
}
TestModel.prototype.setName = function (name) {
this.name = name;
this.publish(name);
};
observable.makeObservable(TestModel.prototype);
return TestModel;
})();
return {
TestModel: TestModel
};
});
TestView.js
define("testView", [],
function () {
var TestView = (function () {
function TestView() {
this.string = "my Name is ";
}
TestView.prototype.talk = function (test, self) {
console.log(self.string + test);
//HERE this.string IS UNDEFINED !!!!, because TestModel called talk()
console.log(this.string + test);
}
return TestView;
})();
return {
TestView: TestView
};
});
testapp.js
define("testapp", ["testModel", "testView"], function (testModel, testView) {
var initialize = function () {
var model = new testModel.TestModel();
var view = new testView.TestView();
model.addSubscriber(view.talk, view);
model.setName("Frank");
}
return {
initialize: initialize
};
});
そして、呼び出してモデルに3つの汎用関数を追加するだけの監視可能なモジュール
makeObservable()
observable.js
define("observable", [],
function () {
/**
* Observable Object, holds 3 geneneric functions.
* @type {{addSubscriber: Function, removeSubscriber: Function, publish: Function}}
*/
var Observable = {
addSubscriber: function (callback, subscriber) {
this.callbacks[this.callbacks.length] = callback;
this.subscribers[this.subscribers.length] = subscriber;
},
removeSubscriber: function (callback) {
for (var i = 0; i < this.callbacks.length; i++) {
if (this.callbacks[i] === callback) {
delete(this.callbacks[i]);
delete(this.subscribers[i]);
}
}
},
publish: function (what) {
for (var i = 0; i < this.callbacks.length; i++) {
if (typeof this.callbacks[i] === 'function') {
this.callbacks[i](what, this.subscribers[i]);
}
}
}
}
/**
* Function takes another function Module and adds the 3
* functions from Observable to it.
*
* @param o
*/
var makeObservable = function (o) {
// turns an object into a publisher
for (var i in Observable) {
o[i] = Observable[i];
o.callbacks = [];
o.subscribers = [];
}
}
return {
makeObservable: makeObservable
};
});
今私の問題に。モデルにサブスクライバーのリストを保持したくありません。これは、ある意味で疎結合の原則に反します。TestModel
しかし、メソッドの にコールバック関数を追加しただけでは、 の変数にsubscribe()
アクセスできません。メソッドを呼び出した TestModel を指しているためです。私の回避策は、モデルにサブスクライバー リストが必要になることです。this.string
TestView
this
talk()
self
また、RequireJS によって呼び出されて返される関数でTestView
、関数の外部で自己変数を初期化しようとしました。TestView
ただし、この関数は 1 回しか呼び出されないため、変数は Java の静的変数のように機能し、 のすべてのインスタンスで一意ではありませんTestView
。
self
関数で/this
変数を取得してtalk()
、文字列を処理せずに文字列にアクセスする可能性はありTestModel
ますか?