2016-04-05 1 views
2

У меня есть DropDownList со следующими привязками:Knockout.js - Предотвратить событие изменения связывания для запуска при установке значения через наблюдаемую

<select data-bind="value: DropDownValue, event: { change: OnChange }"> 
    <option value="1">Val 1</option> 
    /* and more */ 
</select> 

Событие OnChange правильно срабатывает, когда пользователь мог выбрать другое значение из DropDownList.

Событие также запускается при обновлении значения наблюдаемого свойства с использованием viewModel.DropDownValue(1).

То, что я пытаюсь достичь, заключается в том, чтобы инициировать событие изменения ТОЛЬКО, когда пользователь устанавливает значение через пользовательский интерфейс.

Возможно ли заблокировать событие изменения при обновлении значения через наблюдаемое?

Это JSFiddle пример: https://jsfiddle.net/5ex5j7jL/3/

+0

какой-либо конкретной причине вы не используйте привязку 'options'? – cl3m

+0

Так что я не знаю, почему вам нужно изменить значение внутри вашей модели, пока вы этого не хотите? ваш пример имеет ошибку здесь, это пример без ошибок https://jsfiddle.net/5ex5j7jL/1/ –

+0

@ cl3m - я использую привязку 'value', потому что DropDownList уже отображается в HTML со всеми необходимыми параметрами. С привязкой 'options' вы должны предоставить массив объектов и позволить нокауту создавать HTML-код для вас. – crushjz

ответ

4

Похоже, один из способов сделать это является использование the isTrusted property из event объекта (true, когда событие было порождено действиями пользователя, false когда генерируется с помощью скрипта):

self.OnChange = function(viewModel, event) { 
    if(event.isTrusted) { 
    console.log("from dropdown"); 
    return; 
    } else { 
    console.log("NOT from dropdown"); 
    // do something 
    } 
}; 

См updated fiddle

EDIT

Конечно, вы должны выполнить некоторые короля механизма, если вы хотите запретить пользователю изменять ниспадающее меню с помощью пользовательского интерфейса:

function ViewModel() { 

    var self = this; 

    self.DropDownValue = ko.observable(); 
    self._original = null; 

    self.OnChange = function(viewModel, event) { 
     if(event.isTrusted) { 
     // rollback the viewModel value to the old one 
     viewModel.DropDownValue(self._original) 
     return false 
     } else { 
     // keep a reference to the latest value for later rollback 
     self._original = ko.unwrap(viewModel.DropDownValue) 
     } 
    }; 
}; 

Смотрите эту updated fiddle

+2

Свойством isTrusted является путь. Но событие, переданное этой функции, является 'jQuery.event' и не выставляет непосредственно свойство' isTrusted'. Мы нуждаемся в этом, используйте 'event.originalEvent.isTrusted' – crushjz

+0

Свойство было выставлено в скрипке. Я был уверен, что есть трюк совместимости, хорошо сделанный, узнав об этом! – cl3m