2016-02-16 3 views
0

Я работаю с листом (v 0.7.7), и у меня есть вызов Ajax, который получает некоторые данные сервера для привязки к моей карте в виде интерактивных текстовых меток. В цикле, где я привязки данных в формате JSON, который я получил от сервера У меня есть следующий код:Событие маркера Leaflet срабатывает в неподходящее время

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

Теперь, хорошие новости, если я прокомментирую связанную с событием часть этого цикла, цикл завершается, и листок ведет себя так, как должен. Однако, когда я связываю событие click, все становится странным. Событие запускается один раз для каждого элемента коллекции, к которой я привязываюсь. Когда данные загружаются с сервера, я получаю предупреждение, которое появляется каждый раз через цикл с идентификатором текущего элемента. Похоже, что его увольняют «onload», а не «onclick». В довершение всего, он также не регистрирует клики по divIcons после загрузки.

Здесь должно быть что-то, что мне не хватает, но я не вижу, что это такое. Какие-либо предложения?

Этот вопрос аналогичен (Marker in leaflet, click event)

Разрешение: Я изменил последнюю строку декларации Divicon для:

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

Это сейчас работает как задумано. Я предполагаю, что странное поведение привязки является результатом не связывания определенной ссылки на метод и листовки с каким-то функциональным кризисом в коде управления событиями.

Я сохранил аргумент «e», поскольку это то, что показывают документы в листе. Я не использую его, но если кто-то еще копирует это, он может понадобиться.

ответ

2

Вы вводите в заблуждение понятия ссылок на функции и вызовы функций, и вы не делаете closure над идентификатором элемента.

Если вы объявляете это:

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

Wow, разумеется. Я смотрел на него пару часов, и вы приходите и прибиваете его. Спасибо за помощь. – MadTigger

+0

Я только что заметил. Поскольку функция, которую мы сопоставляем с событием клика, является закрытием, когда я помещаю этот код в цикл, все элементы сопоставляются с одним и тем же идентификатором. (Все элементы смотрят на идентификатор, который после окончания цикла заканчивается последним идентификатором). Я пытался выписать вызов функции в виде строки в тег, чтобы каждый тег листовки не содержал ссылку на одно и то же значение. Мне нужно переосмыслить это. – MadTigger

+0

Нет - точка замыкания заключается в том, чтобы предотвратить именно это, определяя собственную область переменных. Я рекомендую вам прочитать документацию о закрытии - я знаю, что они сложны в освоении. – IvanSanchez