3

我正在尝试在 contenteditable div 中突出显示匹配的文本(使用 ngModel $formatters 和 $parsers)。渲染后不会突出显示,并且侦听 ngModel 更改以更新 HTML 会随着每次更改移动插入符号。

即,在 $viewValue 中键入 'search' 后应转换为 (SEARCH) 并在 $modelValue 中保持 'search'(或本例中为 SEARCH),如果删除 'h' 关闭 'search 则删除括号'

编辑我编辑了 plunkr,现在有两个字段绑定到同一个模型(一个输入,一个 contenteditable pre,但这并不重要)——当你在一个中进行更改时,另一个获取 $modelValue 更改并通过 $formatters 推送它,但进行更改的 div 不会接收更改。我希望所有 div(无论是一个还是多个)$parse 和 $format 在 $viewValue 更改时都可以。

http://plnkr.co/edit/H4Cw5t?p=preview

HTML

<pre ng-model="someString" highlight-search contenteditable="true"></pre>

JS

app.directive('contenteditable', function() {
  return {
    require: '?ngModel',
    link: function(scope, element, attrs, ctrl) {
      if(!ctrl) return;

      // view -> model
      element.bind('keyup', function() {
        var key = event.keyCode;
        if (key === 91 || (15 < key && key < 19) || (37 <= key && key <= 40)) return;

        var value = element.html();

        if (ctrl.$modelValue !== value) {
            scope.$apply(function() {
                ctrl.$setViewValue(value);
            });
            //element.html(ctrl.$viewValue);   //messes up cursor position
        }

        console.log(ctrl.$modelValue, '\n', ctrl.$viewValue);
      });

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

app.directive('highlightSearch', function() {
    return {
        restrict: 'A',
        require: 'ngModel',
        link : function(scope, element, attrs, ngModel) {
            var highlightSites = function (input) {
                return input.replace(/search/gi, '(SEARCH)');
            };

            var unhighlightSites = function (input) {
                return input.replace(/[^A-Z ]/ig, '');
            };

            ngModel.$parsers.push(unhighlightSites);
            ngModel.$formatters.push(highlightSites);
        }
    }
});
4

0 回答 0