剣道の控えめな JavaScript スタイルのイベント呼び出しがthis
、私のメソッド コンテキストで壊れているようです。
Foo
としてインスタンス化されたオブジェクトがあるとしますbar = new Foo()
function Foo(){};
Foo.prototype.name = "Herring";
Foo.prototype.doSomething = function(e) {
alert(this.name);
};
bar = new Foo();
たとえば、データクリックを使用してイベントを添付します
<a data-role="button" data-click="bar.doSomething">Click Me</a>
オブジェクト コンテキスト tobar
は置き換えられます (便利element
なコンテナーがあるため、理由はわかりません) this.name
。未定義です。
オブジェクトコンストラクターで古いものを試しましたが、うまくいきませんvar self = this;
。これを解決する最善の方法を知っている人はいますか?
更新:ハッキーな回避策
モジュールをクラスとしてラップする利点を失いたくないので、適切なオブジェクトのメソッドを呼び出すイベント呼び出し関数ラッパーを作成しました。
たとえば、マークアップをラッパー関数に接続します。
<a data-role="button" data-click="doSomething">Click Me</a>
ラッパー関数は object.method を呼び出すだけです。
function doSomething(e){ bar.doSomething(e) };
これで意図した結果が得られますが、非常に恐ろしいことです。マークアップから呼び出されるすべてのイベントには、上記のようなプロキシ関数が必要です。300 のイベントがあるシナリオを想像してみてください...そして、これが恐ろしい理由がすぐにわかります。
他に解決策がない場合は、それがあることを心から願っています。この回避策を回答として投稿しますが、私に関する限り、望ましいとは言えません。
脚注
正直なところ、マークアップからイベントを呼び出すこの方法は「剣道のやり方」であるため、これは剣道の主要なアーキテクチャ上の欠陥のように思えます。おそらくかなりの量のコードthis
が html 要素への参照として既に処理されているため、パッチを適用することはできません。
それをオーバーライドできること、またはこれらのイベント呼び出しを呼び出しを渡すことができる汎用ハンドラー (本質的には汎用プロキシ関数) を介してルーティングできることが、これに対処できる可能性のある方法です。オブジェクトの単純な構成可能な値にすることもできkendo.
ます。
理論解
これが機能する場合は、フォローアップを投稿します。理論的には、汎用プロキシでイベントをスローし、適切にスコープされた関数を呼び出すことができます。
イベント属性を使用してプロキシを呼び出し、オブジェクト/メソッド呼び出しを伝達する別の属性を作成するとします。例えば。
<a data-role="button" data-click="prox" data-prox="o.eventHandler">Click Me</a>
プロキシ関数はprox
、属性データセットからプルします。
メソッド - eval の使用
私が悪いからではありませんが、必要があります。
// sitting in global namespace
function prox(e){
var p = e.sender.element.data['prox'];
// make sure our delegate is a function.
if("function" == eval("typeof "+p)) {
eval(p + "(e)");
}
}
明らかに、これを行うためのより良い方法が必要ですが、少なくとも DRY です。
(すぐに非評価メソッドをクックします...)
評価を開始...
オブジェクト/メソッドを見つけるためにウィンドウコンテキストを使用しましょう。
function prox(e) {
var p = e.sender.element.data['prox'];
if(p.indexOf(".") == -1){
// global function : where *this* is window.
// check you've got the function if not ditch it.
if("function" == typeof window[p]) window[p](e);
} else {
// object/method (one level deep only.)
var s = p.split(".");
var o = s[0], m = s[1];
// check the object/method is a function before executing it.
if("function" == typeof window[o][p]) window[o][p](e);
}
}
もちろん、グローバル(ウィンドウ)スコープの関数の場合、これは要素としておそらくより便利ですが、その場合、選択肢があります。