Knockout.JS: Триггеры, основанные на изменениях наблюдаемого

У меня есть элемент ввода, который связан с наблюдаемым нокаутом:

<input type="text" data-bind="value: myText, valueUpdate: 'keyup'" />

Это обновляет наблюдаемое на каждой клавиатуре. Теперь я хочу инициировать дополнительные события при изменении значения.

Следующее делает это в принципе:

this.myTextTrigger = ko.computed( function () {
    console.log( this.myText() );
}, this );

Однако, это кажется несколько неуклюжим. Он также запускается при первоначальном создании шаблона, где я только хочу обрабатывать изменения после этого. Есть ли официальный/более простой способ инициировать события, основанные на изменениях наблюдаемых?

Ответы

Ответ 1

Используйте подписку:

this.myText.subscribe(function (newText) {
   console.log(newText);
});

Если вы хотите повторно использовать этот триггер, вы можете рассмотреть вопрос об использовании пользовательской привязки.

Ответ 2

Если вы пытаетесь получить дополнительную информацию в своей привязке, используйте allBindings.get( nameOfOtherBinding ) и установите параметр nameOfOtherBinding, чтобы ссылаться на имя привязки в этом элементе который указывает на функцию. Либо поставьте литерал функции в HTML или убедитесь, что вы можете найти эту функцию в области определения обработчиков (например, глобально привязан к объекту window).

http://knockoutjs.com/documentation/custom-bindings.html

Пример скрипта JS - http://jsfiddle.net/pqb4xubg/

javascript, который настроил обработчик (либо в init, либо update):

ko.bindingHandlers.generic = {
    init: function(element, valueAccessor, allBindings){
        var val = 'nothing';
        // set your other bindings to get pulled in
        var func = allBindings.get('func');
        // normal check if the binding is actually a function
        if(typeof func === 'function'){
            // use the retrieved function
            val = func(valueAccessor());
        }
        element.innerText = val;
    }
};
var model = {a:'4', b:5};
ko.applyBindings(model);

html, который будет использовать обработчик (обратите внимание, как элементы с "забавным" связыванием не работают):

<div data-bind="generic: a, func: function( val ){ return val + 2; }"></div>
<div data-bind="generic: a, fun: function( val ){ return val + 2; }"></div>
<div data-bind="text: a"></div>
<div data-bind="generic: b, func: function( val ){ return val + 2; }"></div>
<div data-bind="generic: b, fun: function( val ){ return val + 2; }"></div>
<div data-bind="text: b"></div>

Вы также можете просто использовать init bind для установки стандартных обработчиков событий DOM и просто явно вызвать эти функции, используя что-то вроде jQuery. Спасибо. Добрый день.