Я создаю пользовательский интерфейс разрешений, у меня есть список разрешений со списком выбора рядом с каждым разрешением. Разрешения представлены наблюдаемым массивом объектов, которые привязаны к списку выбора:
<div data-bind="foreach: permissions">
<div class="permission_row">
<span data-bind="text: name"></span>
<select data-bind="value: level, event:{ change: $parent.permissionChanged}">
<option value="0"></option>
<option value="1">R</option>
<option value="2">RW</option>
</select>
</div>
</div>
Теперь проблема заключается в следующем: событие изменения возникает, когда пользовательский интерфейс заполняется впервые. Я вызываю свою функцию ajax, получаю список разрешений, а затем событие возникает для каждого из элементов разрешений. Это действительно не то поведение, которого я хочу. Я хочу, чтобы он поднимался только тогда, когда пользователь действительно выбирает новое значение для разрешения в списке выбора , как я могу это сделать?
источник
select
элементу. Однако даже когда начальное значение select совпадало с одним из вариантов,change
событие все равно запускалось . Когда я реализовал этот простойif
блок в обработчике, все заработало, как ожидалось. Сначала попробуйте этот метод. Спасибо, @Sarath!Это всего лишь предположение, но я думаю, что это происходит, потому что
level
это число. В этом случаеvalue
привязка вызоветchange
событие для обновленияlevel
строкового значения. Поэтому вы можете исправить это, убедившись, чтоlevel
это строка, с которой нужно начинать.Кроме того, более «нокаутный» способ сделать это - не использовать обработчики событий, а использовать наблюдаемые объекты и подписки. Сделайте
level
наблюдаемый, а затем добавьте к нему подписку, которая будет запускаться при каждомlevel
изменении.источник
Вот решение, которое может помочь в этом странном поведении. Я не мог найти лучшего решения, чем разместить кнопку для ручного запуска события изменения.
РЕДАКТИРОВАТЬ: Возможно, такая настраиваемая привязка может помочь:
ko.bindingHandlers.changeSelectValue = { init: function(element,valueAccessor){ $(element).change(function(){ var value = $(element).val(); if($(element).is(":focus")){ //Do whatever you want with the new value } }); } };
И в вашем атрибуте select data-bind добавьте:
источник
Я использую эту настраиваемую привязку (на основе этой скрипки Р.П. Нимейера, см. Его ответ на этот вопрос), которая обеспечивает правильное преобразование числового значения из строки в число (как было предложено решением Майкла Беста):
Javascript:
ko.bindingHandlers.valueAsNumber = { init: function (element, valueAccessor, allBindingsAccessor) { var observable = valueAccessor(), interceptor = ko.computed({ read: function () { var val = ko.utils.unwrapObservable(observable); return (observable() ? observable().toString() : observable()); }, write: function (newValue) { observable(newValue ? parseInt(newValue, 10) : newValue); }, owner: this }); ko.applyBindingsToNode(element, { value: interceptor }); } };
Пример HTML:
<select data-bind="valueAsNumber: level, event:{ change: $parent.permissionChanged }"> <option value="0"></option> <option value="1">R</option> <option value="2">RW</option> </select>
источник
Если вы используете наблюдаемый вместо примитивного значения, выбор не вызовет события изменения при начальной привязке. Вы можете продолжить привязку к событию изменения, а не подписываться непосредственно на наблюдаемое.
источник
Быстро и грязно, используя простой флаг:
var bindingsApplied = false; var ViewModel = function() { // ... this.permissionChanged = function() { // ignore, if flag not set if (!flag) return; // ... }; }; ko.applyBindings(new ViewModel()); bindingsApplied = true; // done with the initial population, set flag to true
Если это не сработает, попробуйте обернуть последнюю строку в setTimeout () - события являются асинхронными, поэтому, возможно, последнее еще не завершено, когда applyBindings () уже вернул.
источник
У меня была аналогичная проблема, и я просто изменил обработчик событий, чтобы проверить тип переменной. Тип устанавливается только после того, как пользователь выберет значение, а не при первой загрузке страницы.
self.permissionChanged = function (l) { if (typeof l != 'undefined') { ... } }
Мне кажется, это работает.
источник
использовать это:
this.permissionChanged = function (obj, event) { if (event.type != "load") { } }
источник
Попробуй это:
self.GetHierarchyNodeList = function (data, index, event) { debugger; if (event.type != "change") { return; } } event.type == "change" event.type == "load"
источник
Если вы работаете с использованием Knockout, используйте ключевую функциональность наблюдаемой функции Knockout.
Используйте
ko.computed()
метод и выполните и вызовите вызов ajax внутри этой функции.источник