0

皆様のお力添えで無事完成いたしました。「context:」を「this.parentNode」から「this」に変更します。私はまだ「これ」の文脈で混乱しています。限られたテストで、複数のインスタンスを実行する際の問題が修正されたようです。ご協力いただきありがとうございます。新しいコードを以下に示します。

私はjQueryとJavascriptが初めてです。データベース テーブル (NavDb) をナビゲートするための一般的なオブジェクトを作成しています。1 つのインスタンスを作成すると、完全に機能します。複数のインスタンスを実行すると失敗します。「これ」の使い方に問題があることを突き止めました。ajax リクエストを初期化/処理する 1 つのルーチンが失敗します。フォームには、任意の数のセレクター (オートコンプリートまたはドロップダウン) を含めることができます。このルーチンは、すべてのセレクターが初期化されるまで ajax リクエストを再帰的に実行します。「this」変数は、「success:」関数に入るときの ajax オブジェクトを参照します。親オブジェクトへの参照が必要なので、2 行目に $this を作成しました。問題は、クロージャーが作成され、2 番目のインスタンスが台無しになることです (それが起こっていると思います)。成功関数内の親オブジェクトへの参照を取得するにはどうすればよいですか? ajax リクエストを親オブジェクトにバインドできますか? 私はこのようなものが必要です:

var $this = this.parent;

うまくいけば、私はこれを明確に説明しました。

新しいコード

NavDb.prototype.getSelData = function () {
    if (this.curSelector >= this.selectors.length) {
        return;
    }
    else {
        var sql = this.selectors[this.curSelector].sql;
        $.ajax({
            url: 'php/select.php',
            type: 'POST',
            context: this,    // Only needed 'this' not this.parentNode.
            dataType: 'json',
            data: {
                'sql': sql
            }
        }).done(function (data) {
            if (data.success) {
                if (data.v.length > 0) {
                    this.selectors[this.curSelector].data = data;
                    if (this.selectors[this.curSelector].type == "autoComp") {
                        this.initAC();
                    };
                    if (this.selectors[this.curSelector].type == "dropDown") {
                        this.initDD();
                    };
                }
            }
            this.curSelector++;
            this.getSelData();
        }).fail(function (XHR, textStatus, errorThrown) {
            $("#status").html(getErrorText(XHR.responseText));
        });
    };
};

古いコード

   NavDb.prototype.ajaxSelData = function () {
        var $this = this;
        if (this.curSelector >= this.selectors.length) {
            $this = null;
            return;
        }
        else {
            var sql = $this.selectors[$this.curSelector].sql;
            $.ajax({
                url: 'php/select.php',
                type: 'POST',
                dataType: 'json',
                data: {
                    'sql': sql
                },
                success: function (data) {
                    if (data.success) {
                        if (data.v.length > 0) {
                            $this.selectors[$this.curSelector].data = data;
                            if ($this.selectors[$this.curSelector].type == "autoComp") {
                                $this.initAC();
                            };
                            if ($this.selectors[$this.curSelector].type == "dropDown") {
                                $this.initDD();
                            };
                        }
                    } else {
                        alert(data.error);
                    }
                    $this.curSelector++;
                    $this.ajaxSelData();
                }
            });
        };
    };
4

2 に答える 2

0

コードが作成するクロージャーは各インスタンスに固有であるため (インスタンスごとに個別のクロージャーを作成します)、クロージャーが 2 番目のインスタンスをめちゃくちゃにするという理論は正しくありません。

したがって、次のように別の変数を作成します。

var $this = this;

行うのはまったく問題なく、問題を引き起こすことはありません。


ただし、親ノードが必要な場合は、おそらく次のようにする必要があります。

var parent = this.parent;    

parent次に、ajax 関数内の変数を参照します。


context引数を ajax 呼び出しに渡すこともできthisます。これにより、成功ハンドラーのコールバックで必要に応じてパラメーターが設定されます。

       $.ajax({
            url: 'php/select.php',
            type: 'POST',
            dataType: 'json',
            context: this.parent,        // add this line
            data: {
                'sql': sql
            },
           success: function (data) {
                // now the this pointer is set as desired in your callback here
                if (data.success) {
于 2013-11-08T21:31:14.007 に答える
0

正しいコンテキスト スコープについては、この回答を参照してください。

いくつかの方法で正しいコンテキストを確保できます。

  • コンテキストを使用

    $.ajax({
         url: 'php/select.php',
         type: 'POST',
         context: this.parentNode,
         dataType: 'json',
         data: {
             sql: sql
         },
         success: function (data) {
             // 'this' is parentNode
         }
    })
    
  • 閉鎖を使用する

    var parentNode = this.parentNode;
    success: function (data) {
        //you can now use 'parentNode'
    }
    
  • $.proxyを使用

    $.proxy(function(data){
        // 'this' is parentNode
    }, this.parentNode);
    
于 2013-11-08T22:11:04.293 に答える