2

我的情况涉及 KnockoutJS 和 jwysiwyg 插件(https://github.com/jwysiwyg/jwysiwyg)。我正在使用下面看到的自定义绑定。但是,每当用户将文本更新到第二行时,通过绑定更新内容会导致光标重置到编辑器的最开头。因此,每当用户在更新后暂停输入超过 1 秒时,他们就会被迫点击回到之前的位置以继续。

    ko.bindingHandlers.wysiwyg = {
        init: function (element, valueAccessor, allBindingsAccessor) {
        var options = allBindingsAccessor().wysiwygOptions || {};
        var value = ko.utils.unwrapObservable(valueAccessor());
        var $e = $(element);
        $.extend(true, {
            initialContent : value
        }, options);

        $e.wysiwyg(options);

        //handle the field changing
        function detectFn() {
            var observable = valueAccessor();
            var newvalue = $e.wysiwyg("getContent");
            observable(newvalue);
        }

        var current = $e.wysiwyg('document');
        var timer;
        current.bind({    
            keyup: function(){
                clearTimeout(timer);
                timer = setTimeout(detectFn, 1000);
            }
        });

        //handle disposal (if KO removes by the template binding)
        ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
            $e.wysiwyg('destroy');
        });
    },
    update: function (element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        $(element).wysiwyg("setContent", value);
        ko.bindingHandlers.value.update(element, valueAccessor);
    }
};

(这个绑定然后被这个使用)

<textarea data-bind="wysiwyg: yourViewModelValue"></textarea>

更新完成后如何获取插入符号位置以恢复光标?或者还有什么其他解决方案可以在更新时强制光标不移动?

编辑:一个 jsfiddle 来演示这个问题。 http://jsfiddle.net/797ZL/ 请注意当您在第二行或之后键入时会发生什么,然后暂停一秒钟,导致光标重置。

4

1 回答 1

3

这是您所看到的:

  1. 用户在所见即所得编辑器中键入一些文本
  2. 用户停止打字,1秒后超时,触发detectFn
  3. detectFn 从 WYSIWYG 编辑器中获取新值并更新您的 observable
  4. 您的 observable 正在更新,触发自定义活页夹上的更新方法
  5. 自定义 binder 上的 update 方法从 observable 中获取值,并在 WYSIWYG 编辑器上进行设置
  6. WYSIWYG 编辑器设置了新值,将光标移动到顶行

您可以通过在第 5 步中间停止操作来解决此问题,并且仅在 WYSIWYG 编辑器中的值与可观察对象中的值不同时才更新该值 - 也就是说,如果可观察对象是从所见即所得编辑器之外的某个位置更新的。

将您的更新方法更改为:

update: function (element, valueAccessor) {
    var newValue = ko.utils.unwrapObservable(valueAccessor());
    var oldValue = $(element).wysiwyg("getContent");
    if (newValue !== oldValue) {
        $(element).wysiwyg("setContent", newValue);
    }
    // ko.bindingHandlers.value.update(element, valueAccessor);
}

我注释掉了该方法的最后一行......它似乎无关紧要,我不确定它为什么在那里。

此外,这些代码行似乎也没有做任何事情:

$.extend(true, {
    initialContent : value
}, options);

我认为您要做的是将 initialContent 属性添加到选项对象。这可以通过这种方式完成:

$.extend(options, {initialContent: value});

但是,即使这样也不需要,因为 update 方法是在 init 方法之后调用的,此时来自 observable 的值被加载到 WYSIWYG 编辑器中。

这是更新代码的小提琴:http: //jsfiddle.net/tlarson/797ZL/2/

于 2013-05-15T03:13:15.127 回答