Настраиваемая привязка редактируемого содержимого нокаута

#javascript #knockout.js #contenteditable

#javascript #knockout.js #редактируемый контент

Вопрос:

Почему в этом примере http://jsfiddle.net/JksKx/8 / div потерял курсор, когда я пишу текст? Как исправить такое поведение?

Ответ №1:

Событие keyup запускается и записывается в вашу viewmodel, которая затем запускает функцию обновления пользовательской привязки. Это записывает innerHTML обратно в элемент, что приводит к потере фокуса.

Простое решение — проверить в функции обновления, совпадает ли element.innerHTML со значением, на которое вы хотите его установить.

http://jsfiddle.net/rniemeyer/JksKx/9/

 ko.bindingHandlers.htmlValue = {
    init: function(element, valueAccessor, allBindingsAccessor) {
        ko.utils.registerEventHandler(element, "keydown", function() {
            var modelValue = valueAccessor();
            var elementValue = element.innerHTML;
            if (ko.isWriteableObservable(modelValue)) {
                modelValue(elementValue);
            }
            else { //handle non-observable one-way binding
                var allBindings = allBindingsAccessor();
                if (allBindings['_ko_property_writers'] amp;amp; allBindings['_ko_property_writers'].htmlValue) allBindings['_ko_property_writers'].htmlValue(elementValue);
            }
        }
                                     )
    },
    update: function(element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor()) || "";
        if (element.innerHTML !== value) {
            element.innerHTML = value;
        }
    }
};
  

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

1. Две вещи, которые я заметил в этой привязке contenteditable: 1. Убедитесь, что привязка данных не находится внутри элемента с атрибутом contenteditable. Элемент с contenteditable не будет запускать ключевое событие. 2. Если пользователь щелкнет правой кнопкой мыши по элементу и вставит текст, это не обновит значение. также должно быть назначено событие щелчка. Также при использовании кнопок типа «жирный» событие щелчка должно быть привязано к телу или чему-то в этом роде.

2. Использование фокуса, похоже, работает для «жирных» событий щелчка и других подобных. ko.utils.registerEventHandler(элемент, «фокус», updateHandler);

Ответ №2:

возможно, потребуется изменить keydown на keyup, но в остальном это работает очень хорошо =)

 ko.utils.registerEventHandler(element, "keyup", function() {