AJAX Call / Jquery / Rails - удаление последней записи в базу данных НЕ указан id [дубликат]

Я искал решение, позволяющее работать $.bind и $.unbind без проблем в динамически добавленных элементах.

Поскольку on () делает трюк для присоединения событий, чтобы создать фальшивую отвязку на тех, к которым я пришел:

const sendAction = function(e){ ... }
// bind the click
$('body').on('click', 'button.send', sendAction );

// unbind the click
$('body').on('click', 'button.send', function(){} );

202
задан Taryn 22 March 2017 в 17:21
поделиться

5 ответов

Представляем себе для объяснения первого примера:

Области JavaScript являются функциональными, а не блочными, а создание замыкания означает, что охватывающая область добавляется в лексическую среду закрытой функции.

После того, как цикл завершается, переменная уровня функции i имеет значение 5, и это то, что внутренняя функция «видит».

Во втором примере для каждого этапа итерации внешний литерал функции будет оценивать новый объект функции со своей собственной областью и локальной переменной num, значение которой установлено на текущее значение i , Поскольку num никогда не изменяется, он будет оставаться постоянным в течение срока действия замыкания. Следующий шаг итерации не перезаписывает старое значение, поскольку объекты функции являются независимыми.

Имейте в виду, что этот подход является довольно неэффективным, поскольку для каждой ссылки необходимо создать два новых функциональных объекта. Это необязательно, поскольку их можно легко обменивать, если вы используете узел DOM для хранения информации:

function linkListener() {
    alert(this.i);
}

function addLinks () {
    for(var i = 0; i < 5; ++i) {
        var link = document.createElement('a');
        link.appendChild(document.createTextNode('Link ' + i));
        link.i = i;
        link.onclick = linkListener;
        document.body.appendChild(link);
    }
}
100
ответ дан Community 19 August 2018 в 19:24
поделиться
  • 1
    Имейте в виду, что расширение DOM (см. link.i = i;) считается плохой практикой . – check_ca 16 February 2014 в 13:44
  • 2
    @check_ca, однако, то же самое можно сделать с атрибутами данных или что-то вроде jQuery's .data (). Обычно они решают проблемы в этой статье (например, данные - зарезервированы для пользователей, поэтому будущий стандарт никогда не будет определять атрибут data-something). – Matthew Flaschen 15 March 2014 в 06:20
  • 3
    «они могут быть легко разделены, если вы используете узел DOM для хранения информации», - очень образованный, спасибо! – Joe Albowicz 3 April 2014 в 19:01
  • 4
    @check_ca Что бы вы порекомендовали вместо этого? По крайней мере, это решение работает, в отличие от закрытых. – Philipp Ludwig 15 August 2017 в 13:54
  • 5
    @PhilippLudwig Я бы рекомендовал заменить link.i = i на link.setAttribute("data-link-index",i) и заменить alert(this.i) на alert(Number(this.getAttribute("data-link-index"))) – check_ca 16 August 2017 в 14:44

Мне нравится писать простые объяснения для толстых людей, потому что я толстый, поэтому здесь идет ...

У нас есть 5 разделов на странице, каждый с идентификатором ... div1, div2, div3, div4, div5

jQuery может это сделать ...

for (var i=1; i<=5; i++) {
    $("#div" + i).click ( function() { alert ($(this).index()) } )
}

Но действительно решая проблему (и медленно ее создавая) ...

ШАГ 1

for (var i=1; i<=5; i++) {
    $("#div" + i).click (
        // TODO: Write function to handle click event
    )
}

ШАГ 2

for (var i=1; i<=5; i++) {
    $("#div" + i).click (
        function(num) {
            // A functions variable values are set WHEN THE FUNCTION IS CALLED!
            // PLEASE UNDERSTAND THIS AND YOU ARE HOME AND DRY (took me 2 years)!
            // Now the click event is expecting a function as a handler so return it
            return function() { alert (num) }
        }(i) // We call the function here, passing in i
    )
}

ПРОСТО ДЛЯ ПОНИМАНИЯ АЛЬТЕРНАТИВА

Если вы не можете опустить голову, тогда это должно быть легче понять и иметь тот же эффект ...

for (var i=1; i<=5; i++) {

    function clickHandler(num) {    
        $("#div" + i).click (
            function() { alert (num) }
        )
    }
    clickHandler(i);

}

Это должно быть понятным, если вы помните, что значения переменных функций задаются при вызове функции (но это использует ту же мысль как и раньше)

76
ответ дан Daniel Lewis 19 August 2018 в 19:24
поделиться
  • 1
    Я замечаю, что вам нужна еще одна версия для +1 для прямой версии! Хотя я думаю, что лично положил бы объявление функции clickHandler за пределы цикла, только для стиля. – Lee Kowalkowski 25 April 2012 в 16:32
  • 2
    Это проблема, которую я все еще не могу понять. когда вы говорите, что значения "установлены, КОГДА ФУНКЦИЯ ВЫЗВАНА & quot; , вы имеете в виду, что только когда CLICKING на div установлено каждое значение div? он постоянно сохраняет объем функции по ссылке – Dima 10 December 2013 в 14:21
  • 3
    Я знаю, что я опаздываю на вечеринку, но в любом случае. Это называется замыканием. Внутренняя функция может обращаться к значениям во внешней функции, даже когда внешняя функция вернулась. Таким образом, внешняя функция является IIFE, поэтому она сохраняет значение num. Когда вы нажимаете, внутренняя функция выполняет и возвращает число. – Alex Shilman 26 August 2015 в 15:33
  • 4
    Я искал какое-то хорошее объяснение закрытия для презентации ... ваш подход, безусловно, самый лучший, престиж. – Juergen Riemer 20 April 2017 в 07:14
  • 5
    Плохо, что это больше не работает, предупреждение просто не будет отображаться, также ничего в консоли. – Philipp Ludwig 15 August 2017 в 13:50

В основном, в первом примере вы привязываете i внутри обработчика onclick непосредственно к i вне обработчика onclick. Поэтому, когда i вне обработчика onclick изменяется, i внутри обработчика onclick тоже изменяется.

Во втором примере вместо привязки к num в onclick, вы передаете его в функцию, которая затем привязывает его к num в обработчике onclick. Когда вы передаете его в функцию, значение i будет скопировано , а не связано с num. Поэтому, когда i изменяется, num остается неизменным. Копия происходит потому, что функции в JavaScript являются «замыканиями», что означает, что как только что-то передается в функцию, оно «закрыто» для внешней модификации.

19
ответ дан Imagist 19 August 2018 в 19:24
поделиться
  • 1
    Я прочитал несколько ответов для этой темы, пытаясь обернуть вокруг себя почему. Последняя половина вашего последнего предложения, наконец, включила свет в моей голове ... спасибо, спасибо, спасибо! – bodine 11 December 2011 в 23:58

Другие объяснили, что происходит, вот альтернативное решение.

function addLinks () {
  for (var i = 0, link; i < 5; i++) {
    link = document.createElement("a");
    link.innerHTML = "Link " + i;

    with ({ n: i }) {
      link.onclick = function() {
        alert(n);
      };
    }
    document.body.appendChild(link);
  }
}

В основном, бедные мужчины несут привязку.

17
ответ дан nlogax 19 August 2018 в 19:24
поделиться

В первом примере вы просто привязываете эту функцию к событию onclick:

function() {alert(i);};

Это означает, что в событии клика js должен предупредить значение функций i-переменной addlink. Его значение будет 5 из-за цикла for ().

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

function (num) {
  return function () { alert(num); };
}

Это означает: если вызов со значением, верните мне функцию, которая будет предупреждать входное значение. Например. вызов function(3) вернет function() { alert(3) };.

Вы вызываете эту функцию со значением i на каждой итерации, поэтому вы создаете отдельные функции onclick для каждой ссылки.

Дело в том, что в первом примере ваша функция содержала ссылку на переменную, а во втором - с помощью внешней функции, которую вы заменили ссылкой фактическим значением. Это называется замыканием примерно потому, что вы «закрываете» текущее значение переменной внутри вашей функции, а не сохраняете ссылку на нее.

5
ответ дан Zed 19 August 2018 в 19:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: