1

jQueryを使用してAjaxリクエストを送信し、レスポンスを処理するメソッドを持つjavascriptクラスがあります。

私が抱えている問題は、jQuery 関数内から初期の親クラスのプロパティを取得する方法がわからないことです。試してみ$(this).parent()ましたが、何らかの理由で必要なものが得られません。

私のコードは以下です。このループから基本クラスに到達する方法を誰か教えてもらえますか?

function companiesPage()
{
    this.childCategoriesSelectid = '#childCategoryid';

    this.setChildCategories = function()
    {
        $.ajax({
            url: this.url,
            dataType: 'json',
            success: function(data)
            {
                $.each(data.childCategories, function()
                {
                    $($(this).parent().childCategoriesSelectid)//problem here
                    .append(
                        $('<option></option>')
                        .attr('value', this.childCategoryid)
                        .text(this.name)
                    );
                });
            }
        });
    }
}
4

2 に答える 2

2

parent()DOMトラバーサル用です。あなたが持っているのはスコーピングの問題です。

this新しい関数スコープを入力するときに、キーワードが常に同じオブジェクトを参照するとは限りません。これは、繰り返されるオブジェクト/要素に.each()設定されるjQueryのメソッドを使用する場合です。this

コンストラクターインスタンスパターンを使用しているように見えるのでthis、var宣言を介してキーワードが参照した元のオブジェクト(インスタンス)への参照を格納するだけです。この参照は、スコープチェーン内で変更できません。

function companiesPage()
{
    var _this = this; //stores a reference to this instance object
    this.childCategoriesSelectid = '#childCategoryid';

    this.setChildCategories = function()
    {
        $.ajax({
            url: this.url,
            dataType: 'json',
            success: function(data)
            {
                $.each(data.childCategories, function()
                {
                    $(_this.childCategoriesSelectid) //NO problem here :)
                    .append(
                        $('<option></option>')
                        .val(this.childCategoryid)
                        .text(this.name)
                    );
                });
            }
        });
    }
}

このようにして、インスタンス内のどこからでもインスタンスのパブリックメソッドとプロパティにアクセスできるようになります。

ps。インスタンス化可能/コンストラクターは通常、慣例により最初の文字を大文字にします。

于 2012-11-16T16:36:40.597 に答える
1

this非同期 Ajax 呼び出しの前にキャプチャする

Ajax 成功ハンドラーは非同期で実行されるため、呼び出し先のコンテキスト (またはスコープ) が失われます。thisフリー変数をキャプチャし、関数クロージャ内でキャプチャされた変数を使用する必要があります。

this2つの意味を期待しているようです

  1. あなたが使用するとき、あなたはいくつかになることを$(this).parent()...期待していますthisHTMLDOMElement
  2. あなたが使用するとき、あなたはあなたの(おそらく配列)のオブジェクトアイテムになることをthis.name期待しています。thisdata

オブジェクト インスタンス参照を取得するソリューション

companyPage がクラスであることが明らかになります (キャメル ケースではなく、パスカル ケースにする必要があります)。したがって、this内の使用。おそらく次の方法で作成します。

var obj = new CompaniesPage();
obj.setChildCategories();

コードは次のようになります。

var CompaniesPage = function()
{
    // keep this as public object property
    this.childCategoriesSelectId = "#childCategoryid";

    // keep this as public object method
    this.setChildCategories = function() {
        // private reference to object instance for later reuse
        var me = this;
        $.ajax({
            url: this.url, // not sure where this one's coming from
            dataType: 'json',
            success: function(data) {
                $.each(data.childCategories, function() {
                    $(me.childCategoriesSelectId).append(
                        $('<option></option>')
                            .attr('value', this.childCategoryid)
                            .text(this.name)
                    );
                });
            }
        });
    }
};

クラスの追加の最適化

また、クラスレベルのメソッドを定義した方法はメモリ効率が悪いことを認識する必要があります。これは、個々のオブジェクト インスタンスが同じメソッドを共有するのではなく、特にメモリ リソースに反映される独自のメソッドを持つためです。同じクラスの複数のインスタンスを作成します。

これはあなたのクラスの最適化されたバージョンです:

var CompaniesPage = function() {
    // keep this as public object property
    this.childCategoriesSelectId = "#childCategoryid";
}

CompaniesPage.prototype.setChildCategories = function() {
    // private reference to me as object instance
    var me = this;

    $.ajax({
        url: this.url, // not sure where this one's coming from
        dataType: 'json',
        success: function(data) {
            $.each(data.childCategories, function() {
                $(me.childCategoriesSelectId).append(
                    $('<option></option>')
                        .attr('value', this.childCategoryid)
                        .text(this.name)
                );
            });
        }
    });
};
于 2012-11-16T16:34:35.923 に答える