在JQuery动态点击处理程序中使用Ajax回调变量值

时间:2009-12-05 17:55:11

标签: javascript jquery

我正在做一个简单的ajax查询,它将可变长度的值列表检索为JSON数据。我正在尝试基于此数据创建一个列表,该列表具有基于我从JSON查询获得的值的单击函数。通过将onClick方法写入HTML,我可以使这项工作正常:

function loadFooList() {
    var list_area = $("#sidebar");
    list_area.html("<ul>")
    $.ajax({
    type: 'GET',
        url:'/data/foo/list',
    dataType: 'json',
    success: function (json) {
        $.each(json, function(i, item) {
        var link_id = "choosesfoo" + item.id;
        list_area.html(list_area.html()
                   + "<li> <a href='#' onClick='alert(\"" + 
                   link_id + "\");'>" + 
                   item.name + "</a></li>");
        });
        list_area.html(list_area.html() + "</ul>");
    }
    });
}

我不喜欢将onClick-function写入HTML,我也想学习如何通过JQuery click-function创建相同的功能。

所以问题显然是变量范围。我的天真尝试显然不起作用,因为点击发生时变量不再存在:

function loadFooList2() {
    var list_area = $("#sidebar");
    var link_ids = Array();
    list_area.html("<ul>")
    $.ajax({
    type: 'GET',
        url:'/data/foo/list',
    dataType: 'json',
    success: function (json) {
        $.each(json, function(i, item) {
        var link_id = "choosefoo" + item.id;
        list_area.html(list_area.html()
                   + "<li> <a href='#' id='" + link_id  + "'>"+item.name+"</a></li>");
        link_ids.push(link_id);
        });
        list_area.html(list_area.html() + "</ul>");
        for (link_index=0; link_index<link_ids.length; link_index++) {
        $("#" + link_ids[link_index]).click(function() {
            alert(link_ids[i]); 
        });
        }
    }
    });
}

显然,除了提醒价值之外,我还想做其他事情,但只要我可以开始工作并继续前进,就会发出提醒电话。

我明白我必须制作某种处理函数,我传递一个状态变量。这适用于单个值(我可以很好地存储整个link_ids数组,但后来我不知道它们中哪个是正确的值),但是如何为任意长度列表执行此操作?

以下是我要复制的示例from JQuery docs

 // get some data
 var foobar = ...;

 // specify handler, it needs data as a paramter
 function handler(data) {
   //...
 }

 // add click handler and pass foobar!
 $('a').click(function(){
   handler(foobar);
 });

 // if you need the context of the original handler, use apply:
 $('a').click(function(){
   handler.apply(this, [foobar]);
 });

我在这里讨论了最后一个例子,“如果你需要原始处理程序的上下文...”可能就是我想要的但我不确切知道如何到达那里。我尝试将当前的link_id值存储到 this 中,在应用函数中使用 this (使用apply()),但是我没有成功。根据FireFox,必要的值仍未定义。我正在使用JQuery 1.3.2。

那么对于这个相对基本的问题,什么是正确的解决方案?

3 个答案:

答案 0 :(得分:3)

使用append代替html()

function loadFooList() {
    var ul = $('<ul>');
    $.ajax({
        type: 'GET',
        url:'/data/foo/list',
        dataType: 'json',
        success: function (json) {
            $.each(json, function(i, item) {
                var link_id = "choosesfoo" + item.id;
                var a = $('<a>').attr('href','#').bind('click', function(e) {
                    alert(link_id,item_name);
                    e.preventDefault();
                });
                $('<li>').append(a).appendTo(ul);
            });
            ul.appendTo('#sidebar');  // this is where the DOM injection happens
        }
    });
}

答案 1 :(得分:1)

所以问题似乎是获取与链接关联的链接ID,以便您的点击处理程序可以访问它。请注意,如果它是字母数字,则它将符合id属性,您可以从那里提取它。如果它纯粹是数字,则它将是非法的id属性。在这种情况下,您可以使用属性(如rel)或jQuery.data()方法来存储链接的链接ID。您还可以使用append进行简化。我将展示两个例子。

var link = $("<li><a href='#' id='" + link_id + "'>" + item.name + "</a></li>";
link.click( function() {
         alert( $(this).attr('id') );
     });
list_area.append(link);

或(如果是数字)

var link = $("<li><a href='#'>" + item.name + "</a></li>";
link.data('identifier', link_id )
    .click( function() {
         alert( $(this).data('identifier') );
     });
list_area.append(link);

答案 2 :(得分:1)

试试这个:

function loadFooList() {
    var list_area = $("#sidebar");
    $.ajax({
        type: 'GET',
        url:'/data/foo/list',
        dataType: 'json',
        success: function (json) {
            var out = '<ul>';
            $.each(json, function(i, item) {
                var link_id = "choosefoo" + item.id;
                out +="<li><a href='#' id='" + link_id  + "'>"+item.name+"</a></li>";
            });
            out +="</ul>"
            var $out = $(out);
            $out.find('a').click(function(){
                var link_id = this.id;
                var item_name = $(this).text();
                alert(link_id);
                alert(link_name);
            })
            list_area.html($out);
        }
    });
}

使用多个附加项导致浏览器连续多次重绘。你只想修改一次dom。