在指令's链接中替换angular元素html

Replacing angular element html within a directive's link

本文关键字:替换 angular 元素 html 链接 指令      更新时间:2023-09-26

这是我的第一个Angular指令。

我试图做一个简单的高亮基于搜索词的html内容,用于找到该内容。

问题是,这只适用于第一项,而不适用于更多项。我想所有的单词得到突出显示,但我做错了,当我替换HTML内容。

这就是指令要做的:

1。指令应该突出显示一个或多个单词。为例。如果搜索词是"文档合法",它应该突出显示它们,即使它们不在这个顺序上。

所以,像"legal something document"这样的文本应该同时突出显示,"legal"answers"document"。

2。如果单词少于3个字符将不会被高亮显示

3。如果没有找到该单词,则尝试从其中删除最后一个字符,直到其长度小于3。你可以搜索"dimensions",搜索引擎可能会返回包含"dimension"甚至"dime"的文本。

为了以防万一,该应用程序是Ionic应用程序。

这是我的代码。

angular指令:

angular.module('starter.directives', [])
.directive('highlightSearchTerms', function($compile) {
  return {
    restrict: 'A',
    scope: true,
    link: function($scope, element, attrs) {
      $scope.highlightTerm = function(term) {
        var html = element.html();
        var highlighted = html.replace(new RegExp(term, 'gi'),
          '<span class="highlightedText">$&</span>');
        if (highlighted == null) {
          return false;
        }
        // @see
        // I think that the problem is here, it works the 
        // first time, but the second time it gets here
        // the following exception is throwed
        // "Cannot read property 'replaceChild' of null"
        element.replaceWith(highlighted);
        return html != highlighted;
      };
      var searchTerms = $scope.searchTerms;
      if (searchTerms != undefined && searchTerms.length < 3) {
        return;
      }
      var terms = searchTerms.split(' ');
      // Try to highlight each term unless the word
      // is less than 3 characters
      for (var i = 0; i < terms.length; i++) {
        var term = terms[i];
        // // Try to highlight unless the word is less than 3 chars
        while (term.length > 2) {
          // If it got highlighted skip to next term
          // else remove a character from the term and try again
          if ($scope.highlightTerm(term)) {
            break;
          }
          term = term.substring(0, term.length - 1);
        }
      }
    }
  };
});

你可以看到一些奇怪的东西。比如使用$scope。highlightTerm,而不是将highlightTerm变量传递给指令。我不能使它工作。

如何正确更改元素的HTML ?

这是使用指令的模板:

<div ng-include src="tplName" highlight-search-terms></div>

我希望这样做,但我不能让它工作:

<div ng-include src="tplName" highlight-search-terms="something to highlight"></div>

这是一个普朗克:http://plnkr.co/edit/BUDzFaTnxTdKqK5JfH0U?p=preview

我认为您的代码正在工作,但问题是您正在尝试替换使用该指令的整个div。所以你能做的就是把element.replaceWith(highlighted);换成element.html(highlighted);,这样就可以了。

我希望做这样的事情,但我不能得到它的工作:<div ng-include src="tplName" highlight-search-terms="something to highlight"></div>

你已经有了,只要在链接函数中使用attrs,像这样:

var terms = attrs.highlightSearchTerms;,你会得到你在highlight-search-terms="something to highlight"中传递的内容

这应该为您工作,使用'compile'函数:

angular.module('starter.directives', [])
.directive('highlightSearchTerms', function($compile) {
  return {
    restrict: 'A',
    scope: true,
    compile: function(elem, attrs) {
        // your code
        elem[0].innerHTML = '<span class="highlightedText">$&</span>';
        // your code
    }
  };
});

文档也有帮助。

即使punov的解决方案有效,我认为您不应该为单个"行"触发多次重新编译。我建议将html存储在一个变量中,并在每个术语被替换后重新编译。

这是一个工作的例子-但它需要一些润色。

http://plnkr.co/edit/3zA54A0F2gmVhCComXAb?p =

预览
link: function($scope, element, attrs) {
  var searchTerms = $scope.searchTerms;
  var terms = searchTerms.split(' ');
  $scope.highlightedHTML = element.html();
  if (searchTerms !== undefined && searchTerms.length < 3) {
    return;
  }
  $scope.highlightTerm = function(term) {
    console.log("html - ", term, html);
    var highlighted =  $scope.highlightedHTML.replace(new RegExp(term, 'gi'),
      '<span class="highlightedText">$&</span>');
    //element.replaceWith(highlighted);
    return highlighted;
  };
  function highlight(terms, compile) {
    // Try to highlight each term unless the word
    // is less than 3 characters
    // if the term is not highlighted remove one character
    // from it and try again
    for (var i = 0; i < terms.length; i++) {
      var term = terms[i];
      while (term.length > 2) {
        var current = $scope.highlightedHTML;
         $scope.highlightedHTML = $scope.highlightTerm(term);

        if (current !==  $scope.highlightedHTML) {
          break;
        }
        term = term.substring(0, term.length - 1);
      }
    }
    compile();
  }

  highlight(terms, function() {
     element.replaceWith( $scope.highlightedHTML);
  });
}