2012-04-27 13 views
1

私はJSONデータ(オブジェクトの配列)を返すajaxリクエストを受け取りました。 この配列を反復すると、リンクのリストが生成されます。 onClickイベントを設定し、ajaxレスポンスのparamsで関数を呼び出したいと思います。それはとてもここでは、明確ではないに聞こえるかもしれJavaScript:動的に生成されたjQueryの.click()関数で関数のパラメータを送信する方法は?

は一例です:私の機能test

function test(param1) { 
    // ... 
} 

$.ajax({ 
    url: 'getSomeData.php', 
    type: 'post', 
    data: data, 
    success: function(result){ 
     var result = JSON.parse(result); 
     $div = $('<div />'); 

     for (i in result.someObject) { 
      $div.append('<a href="#" id="linkID' + i + '">ajax link ' + i + '</a>'); 
      $('#linkID' + i).click(function(){ 
       test(result.someObject[i]); // <--- My question is here 
       return false; 
      }); 
     } 
     $(document.body).append($div); 
    } 
}); 

私は常に反復配列の最後のオブジェクトを取得します。なぜこのようなことが起こったのか考えていますが、修正方法はわかりません。

+0

@Anonymooseで「イベント・データを渡す」の項を参照してください。それが宣言されていれば、まったく同じように失敗するでしょう。 – Alnitak

答えて

4

それはスコープを持つ問題です私の場合、クロージャを使用してその範囲を以下のようなクリックイベントハンドラに制限すると、それはうまくいくはずです。

(function(i) { 
    $('#linkID' + i).click(function(){ 
    test(result.someObject[i]); // <--- My question is here 
    return false; 
    }); 
})(i); 

これにより、ハンドラが最後に設定された値ではなく、ハンドラが作成されたときの値になることが保証されます。

+0

これは正しいですか? '(function(i、j){/ * ... * /}(i、j);'複数の変数のスコープを制限したいのですか?最後の部分 '})(i);'それは何ですか? – SaltLake

+1

@SaltLakeはい、それは複数のパラメータの正しい構文です。最後の部分は、指定されたパラメータでただちにその関数を呼び出します。 'eventData'メソッドで複数のパラメータを追加することも簡単です。マップに追加するだけです。 – Alnitak

0

あなたは簡単な例jQuery.proxy()

使用してコンテキスト(したがって変数)を渡すことができますjQueryのドキュメントから

MyObject = function() { 
    this.element = $('#element'); 
    this.some_var = 'It works!'; 

    this.element.click($.proxy(this.handleClick, this)); 
}; 

MyObject.prototype.handleClick = function() { 
    console.log(this.some_var); 
}; 

var m = new MyObject(); 

例:

<script> 
var me = { 
    type: "zombie", 
    test: function(event) { 
    // Without proxy, `this` would refer to the event target 
    // use event.target to reference that element. 
    var element = event.target; 
    $(element).css("background-color", "red"); 

    // With proxy, `this` refers to the me object encapsulating 
    // this function. 
    $("#log").append("Hello " + this.type + "<br>"); 
    $("#test").unbind("click", this.test); 
    } 
}; 

var you = { 
    type: "person", 
    test: function(event) { 
    $("#log").append(this.type + " "); 
    } 
}; 

// execute you.test() in the context of the `you` object 
// no matter where it is called 
// i.e. the `this` keyword will refer to `you` 
var youClick = $.proxy(you.test, you); 


// attach click handlers to #test 
$("#test") 
    // this === "zombie"; handler unbound after first click 
    .click($.proxy(me.test, me)) 
    // this === "person" 
    .click(youClick) 
    // this === "zombie" 
    .click($.proxy(you.test, me)) 
    // this === "<button> element" 
    .click(you.test); 
</script> 
2

あなたの問題はスコープの1つです。変数iはスコープ内にバインドされていませんので、イベントハンドラが呼び出された時点で常に最後の値が割り当てられています。

(あなたはjQueryのを使用しているとして)これを解決する最も簡単な方法は.click()eventDataパラメータを使用することです。その後、

('#linkID' + i).click({ param1: result.someObject[i] }, test); 

とイベントデータを読み取るためにtestを変更:

function test(ev) { 
    var param1 = ev.data.param1; 
    // ... 
} 

jQueryは、指定された任意のeventDataをバインドし、イベントハンドラに渡されるイベントオブジェクトに自動的に追加します。

これにより、指定されたパラメータのスコープを修正するために追加のクロージャを作成する必要がなくなります。

は本当、しかし説明したバグには無関係http://api.jquery.com/bind/

関連する問題