Автозаполнение не с использованием правильного ссылочного вызова

#javascript #jquery #for-loop #autocomplete

#javascript #jquery #for-цикл #автозаполнение

Вопрос:

У меня есть функция, которая создает мои автозаполнения. При нормальных обстоятельствах это работает просто отлично. Примером вызова функции является:

 getList('employee', { type: 'auto', id: 'txtMgrID', callback: function (id) { $('#hidMgrID').val(id); } });
 

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

Проблема, с которой я сталкиваюсь, заключается в том, что я создаю это в цикле. У меня есть диалоговое окно, в котором будет несколько автозаполнений сотрудника. Итак, я создаю раздел диалогового окна с помощью цикла (поэтому он создает txtMgr0 — txtMgr4 вместе с hidMgrID0 — hidMgrID4 ). И диалоговое окно может создавать любое их количество (в зависимости от того, сколько прямых сотрудников у данного менеджера), поэтому я использую цикл для этого.

После открытия диалогового окна я использую другой цикл for для выполнения вызова создания автозаполнения. Мой точный код:

 for (x = 0; x < mgrcnt; x  ) { 
    getList('employee', { type: 'auto', id: 'txtMgr'   x, callback: function (id) { $('#hidMgrID' x).val(id); } }); 
}
 

Теперь проблема, с которой я сталкиваюсь, заключается в том, что ВСЕ текстовые поля автозаполнения обновляют ПОСЛЕДНИЙ hidID … это как если бы в моем примере $(‘#hidMgrID’ x) вычисляется как $(‘#hidMgrID4’) для каждого вызова getList в цикле. Что странно, так это то, что если я помещу вызов предупреждения как перед вызовом get list (как часть цикла), так и в ссылку на функцию обратного вызова (перед ссылкой на jquery .val ), и по мере загрузки диалогового окна он выдаст мне #hidMgrID0, затем 1, затем 2 и т. Д. Через всеиз них, а затем, когда я ввожу диспетчер в текстовый элемент, он предупреждает #hidMgrID4 для ВСЕХ из них.

Я не понимаю, почему это происходит… и любая помощь, чтобы разобраться в этом, была бы признательна!

Заранее спасибо!

Крис

Ответ №1:

У вас проблема с областью действия: вы создаете функцию и сохраняете ее в свойстве обратного вызова, но переменная x вычисляется не сразу. Поэтому, когда ваша функция выполняется и вычисляется x, переменной x является mgrcnt, так как for уже закончился.

Возможным решением является использование этой идеи:

Что вы делаете:

 var arr=[];
for(var i=0;i<10;i  ){
    arr[i] =function(){
        console.log(3 i);
    }
}
console.log(i); // 10
arr[0](); // 13
arr[1](); // 13
 

Что вы должны сделать:

 var arr=[];
for(var i=0;i<10;i  ){
    (function(){
    var x=i;
        arr[x] =function(){
            console.log(3 x);
        }
    }())
}
console.log(i); // 10
arr[0](); // 3
arr[1](); // 4
 

Комментарии:

1. Нет — это не сработало правильно… в итоге мне пришлось создать функцию, которая возвращает нужную мне функцию… function makeCallback(i) { return function(id) { $('#hidMgr' i).val(id); } } затем ссылается на мой обратный вызов, чтобы использовать makeCallback!

Ответ №2:

В итоге я придумал свой собственный ответ после дополнительных исследований — в основном мне пришлось создать внешнюю функцию, которая возвращала нужную мне функцию:

 function makeCallback(i) { 
    return function(id) { $('#hidMgr' i).val(id); } 
}
 

затем я смог использовать его в своем цикле for:

 for (x = 0; x < mgrcnt; x  ) { 
    getList('employee', { type: 'auto', id: 'txtMgr'   x, callback: makeCallback(x) }); 
}
 

Это решило мою проблему.