Использование значений переменных обратного вызова Ajax в динамических обработчиках кликов JQuery - PullRequest
0 голосов
/ 05 декабря 2009

Я делаю простой запрос 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-функцию в 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, но тогда я не знаю, какое из них является правильным значением для этой ссылки), но как мне это сделать для списков произвольной длины?

Вот пример из документации JQuery , который я пытаюсь скопировать:

 // 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 ]

3 голосов
/ 05 декабря 2009

Используйте 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 голос
/ 05 декабря 2009

Попробуйте это:

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);
        }
    });
}

Использование нескольких добавлений, вызывающих перерисовку браузера несколько раз подряд. Вы хотите изменить дом только один раз.

1 голос
/ 05 декабря 2009

Таким образом, проблема заключается в получении идентификатора ссылки, связанного со ссылкой, чтобы ваш обработчик кликов имел к ней доступ. Обратите внимание, что если он буквенно-цифровой, он будет соответствовать атрибуту id, и вы можете извлечь его оттуда. Если он чисто числовой, это будет недопустимый атрибут id. В этом случае вы можете использовать атрибут, например rel, или метод jQuery.data () для хранения идентификатора ссылки со ссылкой. Вы также можете упростить с помощью добавления. Я покажу оба примера.

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...