7

この質問は賛成票を投じたばかりなので、私がしたことで質問を更新できます

ウィンドウオブジェクト(またはユーザー指定のオブジェクトルート)を繰り返し処理することで解決し、正しいインスタンスが見つかったら、バックトラックしてインデックスから名前を取得しました。最終的な解決策はここにあります

https://github.com/AndersMalmgren/Knockout.BindingConventions

更新終了

KnockoutJS / MVC の構成テンプレート ソース エンジンに関する規則を作成する予定です。私は小さなクライアント側の POC から始めて、すぐにショー ストッパーに遭遇しました。

私の計画は、この構文または類似のものを使用することです

MyApp.EditCustomersViewModel = function() {
   ko.templates.loadView(this);
};

これを行うと、オブジェクト名をキーとして使用して、tamplate キャッシュをチェックするか、サーバーからテンプレートをフェッチします。問題は、プロトタイプオブジェクトの名前を取得できないことです。これを試しました

Object.prototype.getName = function() {
   var funcNameRegex = /function (.{1,})\(/;
   var results = (funcNameRegex).exec((this).constructor.toString());
   return (results && results.length > 1) ? results[1] : "";
};

このように定義されたオブジェクトで機能する場合

function MyClass() { 
}

上記のオブジェクトにプロトタイプを追加すると機能しないか、このように定義すると

MyApp = {};
MyApp.MyClass = function() {
};

プロトタイプとスコーピングは 2 つの必須事項なので、これはショーストッパーです。何かアイデアはありますか?

フィドル: http://jsfiddle.net/aRWLA/

編集:これの背景は次のとおりです。

サーバー上には、このような構造があります

  • Templates\ [ViewName]\index.html
  • Templates\ [ViewName]\sub-model-template.html

あなたがするクライアントで

MyApp.EditCustomersViewModel = function() {
   ko.templates.loadView(this);
};

オブジェクト名をキーとして ajax リクエストを生成し、問題のビューのすべてのテンプレートを取得します

4

4 に答える 4

4

巻き上げられた関数 ( function someFunc() {) のみが取得可能な名前を持ちます。

技術的に関数に名前を付けるのではなく、匿名関数を作成し、それへの参照を (メモリ内で) 名前付き変数に割り当てるため、割り当てられた関数はそうではありません。

したがって、名前が付けられるのは関数ではなく var です。

これにより、関数名を取得するというアイデア自体が、ほとんど手始めにできなくなります。漠然と成熟したパターンでは、巻き上げられた関数ではなく、メソッドを作成することになるためです。もちろん、メソッドには関数が割り当てられます。

名前付き式(他の回答を参照)は部分的な回避策ですが、これらには他の問題があります-特に古いIEでのサポートの欠如。

(補足: 割り当てられた関数の名前を取得できるように、ブラウザー ベンダーがこれに基づいて構築することを長い間期待していましたが、まだ満足していません。)

于 2012-08-24T08:55:39.517 に答える
2

関数プロトタイプの不適切な置き換えに問題があると思います。関数プロトタイプオブジェクトを置き換える場合は、constructorメンバーをプロトタイプに保持する必要があります。

function Test1() {
}
Test1.prototype={
  constructor: Test1
};

MyApp={};
MyApp.MyClass=function MyClass(){
};
MyApp.MyClass.prototype={
  constructor: MyApp.MyClass
};

あなたの例: http://jsfiddle.net/aRWLA/1/

修正例: http: //jsfiddle.net/aRWLA/2/

于 2012-08-23T11:15:12.507 に答える
1

名前付き関数式を利用できます:

MyApp.MyClass = function MyClass() { ... };

ただし、(驚いたことに) IE のすべてのバージョンで正しく動作するわけではないことに注意してください。

参照: http://kangax.github.com/nfe/

于 2012-08-23T10:54:10.220 に答える
1

これは質問に答えません

ただし、コードは他の人にも役立つ可能性があるため、念のためここに残しておきます。賛成票は期待していませんが、反対票を投じても悪用しないでください。ありがとう。


私はあなたのユースケースを知りません.そのため、設計上の問題があると思います-あなたが説明した問題は実際には発生しないはずです.

しかし、これを機能させる必要があるとしましょう。必要なことを行う簡単な方法は次のようになります。

function findNamed(obj, fn){
    for(var p in obj)
        if(obj[p] === fn)
            return p;
    return false;
}

var m = {};
m.MyClass = function() {};

console.log(findNamed(m, m.MyClass));

もちろん、ソリューションをより適切な OOP 形式にすることもできますが、これはアイデアを示すためのものです。

ユースケースを再現するには、次のようになります。

m.MyClass = function() {
    findNamed(this, arguments.callee);
};

したがって、最終的なコードは次のとおりです。

Object.prototype.getNameOfCall = function(fn) {
    for(var p in this)
        if(this[p] === fn)
            return p;
    throw "Callback not in object.";
};

var m = {};
m.MyClass = function() {
    console.log(this.getNameOfCall(arguments.callee)); // MyClass
};

m.MyClass(); // test it out
于 2012-08-23T11:01:07.830 に答える