Как я могу получить нокаут JS для привязки данных на KeyPress вместо потерянного фокуса?

StackOverflow https://stackoverflow.com/questions/4386311

  •  10-10-2019
  •  | 
  •  

Вопрос

Этот пример нокаут JS Работает так, когда вы редактируете поле и нажмите вкладку, данные ViewModel и, следовательно, текст под полями обновляется.

Как я могу изменить этот код так, чтобы данные ViewModel обновлялись каждый ключ?

alt text

<!doctype html>
<html>
    <title>knockout js</title>
    <head>
        <script type="text/javascript" src="js/knockout-1.1.1.debug.js"></script>
        <script type="text/javascript">
        window.onload= function() {

            var viewModel = {
                firstName : ko.observable("Jim"),
                lastName : ko.observable("Smith")
            };
            viewModel.fullName = ko.dependentObservable(function () {
                return viewModel.firstName() + " " + viewModel.lastName();
            });

            ko.applyBindings(viewModel);
       }
        </script>
    </head>
    <body>
        <p>First name: <input data-bind="value: firstName" /></p>
        <p>Last name: <input data-bind="value: lastName" /></p>
        <h2>Hello, <span data-bind="text: fullName"> </span>!</h2>
    </body>
</html>
Это было полезно?

Решение

<body>
        <p>First name: <input data-bind="value: firstName, valueUpdate: 'afterkeydown'" /></p>
        <p>Last name: <input data-bind="value: lastName, valueUpdate: 'afterkeydown'" /></p>
        <h2>Hello, <span data-bind="text: fullName"> </span>!</h2>
</body>

От документация

Дополнительные параметры

  • valueUpdate

    Если ваша привязка также включает параметр, называемый ValueUpdate, это определяет, какое событие браузера KO должно использовать для обнаружения изменений. Следующие строковые значения являются наиболее часто полезными вариантами:

    • «Изменить» (по умолчанию) - обновляет модель вашего представления, когда пользователь перемещает фокус на другой элемент управления или в случае элементов, сразу после любого изменения

    • «KeyUp» - обновляет модель вашего представления, когда пользователь выпускает ключ

    • «Keypress» - обновляет модель вашего представления, когда пользователь набрал ключ. В отличие от Keyup, это неоднократно обновляется, пока пользователь удерживает ключ.

    • «AfterKeyDown» - обновляет модель вашего представления, как только пользователь начнет печатать символ. Это работает, поймав событие браузера Keydown и асинхронно обрабатывая событие.

Из этих вариантов «AfterkeyDown» является лучшим выбором, если вы хотите обновляться модели представления в режиме реального времени.

Другие советы

В Версия 3.2 Вы можете просто использовать TextInput Привязка.:

<input data-bind="textInput: userName" />

Это делает две важные вещи:

  • Сделайте немедленные обновления
  • Обрабатывает различия в браузерах для выреза, перетаскивания, автозаполнения ...

Таким образом, нет необходимости в дополнительных модулях, пользовательских управлениях и других вещах.

Если вы хотите, чтобы он сделал обновления о afterkeydown «По умолчанию», вы можете ввести valueUpdate связывание в value обработчик связывания. Просто поставьте новый allBindingsAccessor Чтобы обработчик использовал, который включает afterkeydown.

(function () {
    var valueHandler = ko.bindingHandlers.value;
    var getInjectValueUpdate = function (allBindingsAccessor) {
        var AFTERKEYDOWN = 'afterkeydown';
        return function () {
            var allBindings = ko.utils.extend({}, allBindingsAccessor()),
                valueUpdate = allBindings.valueUpdate;

            if (valueUpdate === undefined) {
                return ko.utils.extend(allBindings, { valueUpdate: AFTERKEYDOWN });
            } else if (typeof valueUpdate === 'string' && valueUpdate !== AFTERKEYDOWN) {
                return ko.utils.extend(allBindings, { valueUpdate: [valueUpdate, AFTERKEYDOWN] });
            } else if (typeof valueUpdate === 'array' && ko.utils.arrayIndexOf(valueUpdate, AFTERKEYDOWN) === -1) {
                valueUpdate = ko.utils.arrayPushAll([AFTERKEYDOWN], valueUpdate);
                return ko.utils.extend(allBindings, {valueUpdate: valueUpdate});
            }
            return allBindings;
        };
    };
    ko.bindingHandlers.value = {
        // only needed for init
        'init': function (element, valueAccessor, allBindingsAccessor) {
            allBindingsAccessor = getInjectValueUpdate(allBindingsAccessor);
            return valueHandler.init(element, valueAccessor, allBindingsAccessor);
        },
        'update': valueHandler.update
    };
} ());

Если вам не удобно «переоценить» value Привязка, вы можете дать версию пользовательского привязки другого имени и использовать этот обработчик привязки.

ko.bindingHandlers.realtimeValue = { 'init':..., 'update':... };

демо

Подобное решение подойдет для нокаутной версии 2.x. Команда нокаута проделала более полное привязку для текстоподобных входов через ввод текста Переплет в нокаутной версии 3 и выше. Он был разработан для обработки всех методов ввода текста для входов текста и textarea. Анкет Он даже будет обрабатывать в реальном времени обновление, которое эффективно делает этот подход устаревшим.

Ответ Джеффа Меркадо фантастический, но, к сожалению, сломан нокаутом 3.

Но я нашел ответ, предложенный Do Devs, работая через нокаут 3 изменения. Смотрите нижние комментарии на https://github.com/knockout/knockout/pull/932. Анкет Их код:

//automatically add valueUpdate="afterkeydown" on every value binding
(function () {
    var getInjectValueUpdate = function (allBindings) {
        return {
            has: function (bindingKey) {
                return (bindingKey == 'valueUpdate') || allBindings.has(bindingKey);
            },
            get: function (bindingKey) {
                var binding = allBindings.get(bindingKey);
                if (bindingKey == 'valueUpdate') {
                    binding = binding ? [].concat(binding, 'afterkeydown') : 'afterkeydown';
                }
                return binding;
            }
        };
    };

    var valueInitHandler = ko.bindingHandlers.value.init;
    ko.bindingHandlers.value.init = function (element, valueAccessor, allBindings, viewModel, bindingContext) {
        return valueInitHandler(element, valueAccessor, getInjectValueUpdate(allBindings), viewModel, bindingContext);
    };
}());

http://jsfiddle.net/mbest/gkjnt/

Редактировать KO 3.2.0 теперь имеет более полное решение с новой привязкой «TextInput». См. Ответ Сальвидордали

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top