AngularJS,實現contenteditable的雙向綁定

前言

在項目中遇到須要使用contenteditable來替代textarea,實現輸入內容的自動高度,可是div或者p這樣的標籤並非一個輸入控件,不能直接被ngModel綁定,這個時候就須要把contenteditable作成一個directive來實現雙向綁定:html

代碼

app.directive('contenteditable', function () {
    return {
        require: 'ngModel',
        link: function (scope, element, attrs, ctrl) {
            /*輸入回車的時候會轉義成<br>被提交,因此去掉回車的輸入*/
            function deleteBr(sHtml) {
                return sHtml.replace(/<br>/g, "");
            }
            // view -> model
            element.bind('input', function () {
                scope.$apply(function () {
                    element.html(deleteBr(element.html()));
                    ctrl.$setViewValue(element.html());
                });
            });

            // model -> view
            ctrl.$render = function () {
                element.html(ctrl.$viewValue);
            };

            // load init value from DOM
            ctrl.$render();
        }
    };
});

注意

  • 在div中輸入回車是會被轉義成
    ,而在實際使用中可能須要禁止回車,因此在directive中須要把回車產生的
    過濾掉;app

  • 在html中須要設置contenteditable="plaintext-only"控制輸入的內容爲純文本,由於複製過來的一些內容可能會被帶上一些文字樣式;ui

  • 在model中輸入<> 會被轉義,解決辦法是在controller裏面先過濾一遍數據(輸出的時候也須要過濾一次)雙向綁定

function html2Escape(sHtml) {
        return sHtml.replace(/[<>&"]/g, function (c) {
            return {'<': '&lt;', '>': '&gt;', '&': '&amp;', '"': '&quot;'}[c];
        });
    }
    $scope.text= html2Escape($scope.text)
相關文章
相關標籤/搜索