0

多くの編集可能な領域を含む文字列があります。この文字列を検討してください

 var str = "Regular ... are patterns used to match character .... in strings. In ..., regular expressions are also objects."

編集可能な領域には ('...') が含まれています。その場所を編集可能にしたいと考えています。その文字列内に編集可能なコンテンツを挿入したいということです。この目的のためにノックアウトを使用したいと思います。ノックアウトを使用して編集可能なコンテンツについてニーマイヤーを参照しました。誰かがこれを達成するためのより良い方法を提案できますか? これは私のコードです

         ko.bindingHandlers.editableContent = {
        init: function(element, valueAccessor, allBindingsAccessor) {

            $(element).css({ "background-color": "#ff77ee", "margin-left": "-2px", "letter-spacing": "0.05"});

            ko.utils.registerEventHandler(element, "keyup", 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'] && allBindings['_ko_property_writers'].editableContent) allBindings['_ko_property_writers'].editableContent(elementValue);
                }
            })
        },
        update: function(element, valueAccessor) {
            var value = ko.utils.unwrapObservable(valueAccessor()) || "";
            element.innerHTML = value;
        }
    };




    ko.bindingHandlers.myBinding = {
        init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {

            var div = document.createElement("div");
            var fulltext = valueAccessor();

            element.appendChild(div);

            div.innerHTML = fulltext().replace(/\.\.\./g, "<span data-bind = 'editableContent : editedText' contenteditable='true'></span>");

            ko.applyBindings(viewModel,div);


        },

        update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {

        }
    };

    $(document).ready(function () {

        var viewModel = function () {
            var self = this;
            self.fullText = ko.observable('Regular ... are patterns used to match character .... in strings. In ..., regular expressions are also objects.');
            self.editedText = ko.observable('...');

        }

        ko.applyBindings(new viewModel());

    });
4

1 に答える 1

2

主な問題は、各 editableContent バインディングが同じオブザーバブルにバインドされているため、互いに更新されていることです。

これは、テキストを断片に分割し、個別の contenteditable ごとに個別の観察可能要素を追加する簡単な試みです。

    ko.bindingHandlers.myBinding = {
        init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
            var div = document.createElement("div"),
                fulltext = valueAccessor(),
                split = fulltext().split(/\.\.\./g),
                span, editable, editableSpan, pieces = [];

            element.appendChild(div);

            //loop through each pieces and add text and editable content
            for (var i = 0, j = split.length; i < j; i++) {
              //create a span for the fixed content
              span = document.createElement("span");
              span.innerHTML = split[i];

              //keep track of each piece, so we can later put them back together to update original
              pieces.push(split[i]);
              div.appendChild(span);

              //add editable content between the pieces, except at the end
              if (i < split.length - 1) {
                editable = ko.observable("...");
                editableSpan = document.createElement("span");
                pieces.push(editable);
                div.appendChild(editableSpan);
                ko.applyBindingsToNode(editableSpan, { editableContent: editable });
              }

            }

            //update the original observable with the current value
            ko.computed({
                read: function() {
                    var result = "";
                    ko.utils.arrayForEach(pieces, function(piece) {
                       result += ko.utils.unwrapObservable(piece); 
                    });

                    valueAccessor()(result);
                },
                disposeWhenNodeIsRemoved: element
            });

            return { controlsDescendantBindings: true };
        }
    };

サンプルはこちら: http://jsfiddle.net/rniemeyer/8CkLn/

これは、編集に基づいて元のオブザーバブルの更新を処理しますが、元のオブザーバブルを別の方法で更新した場合、コンテンツの編集可能なブロックの更新は処理しないことに注意してください。

于 2013-05-23T14:23:20.543 に答える