Събитието за маркер на листовка се задейства в грешен момент

Работя с листовка (v 0.7.7) и имам извикване на Ajax, което получава някои данни от сървъра, за да се свърже с моята карта под формата на текстови етикети, върху които може да се кликне. В цикъла, в който обвързвам JSON данните, които получих от сървъра, имам следния код:

var item_name = L.marker([data.X, data.Y],
{
    icon: L.divIcon(
    {
        className:'MapTag', 
        iconAnchor: [10, 10],
        html:'<img src="/Images/Map/Item' + data.Id + '.png">' + data.Name 
    })
}).on('click', onItemClick(data.Id));

item_layer.addLayer(item_name);

На друго място имам кода onItemClick:

function onItemClick(item_id)
{
    alert(item_id);
}

Сега, добрата новина, ако коментирам частта за свързване на събитието от това, цикълът завършва и листовката се държи както трябва. Въпреки това, когато обвържа събитието за щракване, нещата стават странни. Събитието се задейства веднъж за всеки елемент в колекцията, към която се свързвам. Когато данните се зареждат от сървъра, получавам предупреждение, изскачащо всеки път през цикъла с идентификатора на текущия елемент. Има усещането, че се задейства „onload“, а не „onclick“. За капак, той също не регистрира кликвания върху divIcons след зареждане.

Трябва да има нещо, което пропускам тук, но не мога да видя какво е то. Някакви предположения?

ТОЗИ въпрос е подобен на (Маркер в листовка, кликване събитие)

Разрешение: Промених последния ред от декларацията divIcon на:

}).on('click', function(e){ alert(data.Id); });

Това вече работи по предназначение. Предполагам, че странното поведение на обвързване е резултат от несвързването на дефинирана препратка към метод и листовка, която има някакъв вид функционален срив в своя код за управление на събития.

Запазих аргумента „e“, тъй като това е, което показват документите на листовката. Не го използвам, но ако някой друг копира и постави това, може да му потрябва.


person Roger Hill    schedule 16.02.2016    source източник


Отговори (1)


Вие обърквате концепциите за препратки към функции и извиквания на функции и не правите затваряне над идентификатора на елемента.

Ако декларирате това:

function onItemClick(id) { alert(id); }

Това отпечатва препратката към функцията:

console.log( onItemClick );

И това отпечатва върнатата стойност от извикването на тази функция (тъй като не връща нищо, това е равно на undefined):

console.log( onItemClick(5) );

Така че, когато правите това:

L.marker(....).on('click', onItemClick(id) );

функцията се извиква и on() получава върнатата стойност на тази функция, т.е.:

L.marker(....).on('click', undefined );

Това, което искате да направите, е да имате функция, която връща функция:

function onItemClick(id) { return function(){ alert(id); } }

По този начин, когато го направите

L.marker(....).on('click', onItemClick(5) );

Това ще направи извикване на функция и ще използва върнатата стойност, която сега изглежда така:

L.marker(....).on('click', function() { alert(5); } );
person IvanSanchez    schedule 16.02.2016
comment
Уау, безумие. Гледах го няколко часа и ти дойде и го закова. Благодаря за съдействието. - person Roger Hill; 16.02.2016
comment
Току що забелязах нещо. Тъй като функцията, която съпоставяме към събитието за кликване, е затваряне, когато поставя този код в цикъл, всички елементи се нанасят на един и същ идентификатор. (Всички елементи разглеждат идентификатора, който след края на цикъла е последният идентификатор) Опитвах се да напиша извикването на функцията като низ към етикета, така че всеки етикет на листовка да не съдържа препратка към същата стойност. Трябва да преосмисля това. - person Roger Hill; 17.02.2016
comment
Не - целта на затварянията е да предотвратят точно това, като дефинират собствен обхват на променлива. Препоръчвам ви да прочетете документацията за затварянията - знам, че са трудни за овладяване. - person IvanSanchez; 17.02.2016