如何在角度2中突出显示段落中的单词?

时间:2016-04-29 11:14:05

标签: angular highlight

我在角度1.x中做了这个,但我想知道如何使用关键字突出角度2..in angular 1.x iam中的动态单词

        <td><div highlight="var" keywords="somename">      {{paragraph}}</div></td>

我使用下面的angular-highlight.js。

完成了上面的html
     angular.module('angular-highlight', [])
      .directive('highlight', function()
    {

    var component = function(scope, element, attrs) {

    if (!attrs.highlightClass) {
        attrs.highlightClass = 'angular-highlight';
    }

    var replacer = function(match, item) {
        return '<span class="'+attrs.highlightClass+'">'+match+'</span>';
    }
    var tokenize = function(keywords) {
        keywords = keywords.replace(new RegExp(',$','g'), '').split(',');
        var i;
        var l = keywords.length;
        for (i=0;i<l;i++) {
            keywords[i] = '\\b'+keywords[i].replace(new RegExp('^ | $','g'), '')+'\\b';
        }
        return keywords;
    }

    scope.$watch('keywords', function() {
        //console.log("scope.keywords",scope.keywords);
        if (!scope.keywords || scope.keywords == '') {
            element.html(scope.highlight);
            return false;
        }


        var tokenized   = tokenize(scope.keywords);
        var regex       = new RegExp(tokenized.join('|'), 'gmi');

        //console.log("regex",regex);

        // Find the words
        var html = scope.highlight.replace(regex, replacer);

        element.html(html);
    });
}
return {
    link:           component,
    replace:        false,
    scope:          {
        highlight:  '=',
        keywords:   '='
    }
};
});

2 个答案:

答案 0 :(得分:8)

我会为此创建一个自定义指令:

@Directive({
  selector: '[highlight]'
})
export class HighlightDirective {
  @Input()
  keywords:string;

  highlightClass: string = 'highlight';

  constructor(private elementRef:ElementRef,private renderer:Renderer) {

  }

  replacer(match, item) {
    return `<span class="${this.highlightClass}">${match}</span>`;
  }

  tokenize(keywords) {
    keywords = keywords.replace(new RegExp(',$','g'), '').split(',');
    return keywords.map((keyword) => {
      return '\\b'+keyword.replace(new RegExp('^ | $','g'), '')+'\\b';
    });
  }  

  ngOnChanges() {
    if (this.keywords) {
      var tokenized = this.tokenize(this.keywords);
      var regex = new RegExp(tokenized.join('|'), 'gmi');

      var html = this.elementRef.nativeElement.innerHTML.replace(regex, (match, item) => {
        return this.replacer(match, item);
      });

      this.renderer.setElementProperty(this.elementRef.nativeElement, 'innerHTML', html);
    }
  }
}

并像这样使用它:

@Component({
  selector: 'app'
  template: `
    <p highlight keywords="test,angular2">
    this is a test to highlight words with angular2
    </p>
  `,
  styles: [`
    .highlight {
      background-color: yellow;
    }
  `]
  directives: [ HighlightDirective ]
})
export class App {
}

根据所使用的ViewEncapsulation,你可能需要一个hack(在模拟的一个 - 默认情况下)来添加一个属性,以便能够看到应用的样式:

replacer(match, item) {
  return `<span ${encapsulationAttribute} class="${this.highlightClass}">${match}</span>`;
}

ngOnChanges() {
  this.initializeEncapsulationAttribute();
  (...)
}

initializeEncapsulationAttribute() {
  if (!this.encapsulationAttribute) {
    var attributes = this.elementRef.nativeElement.attributes;
    for (var i = 0; i<attributes.length; i++) {
      let attr = attributes[i];
      if (attr.name.indexOf('_ngcontent') != -1) {
        this.encapsulationAttribute = attr.name;
        break;
      }
    }
  }
}

请参阅此plunkr:https://plnkr.co/edit/XxB1pFEyUHlZetxtKMUO?p=preview

答案 1 :(得分:6)

如果有人对简单(通用)解决方案感兴趣,我想出了一个指令(基于Thierry Templier工作!)。

此指令允许您传递要使用的文本,搜索文本和要应用的类:

import { Directive, ElementRef, Renderer, Input, OnInit } from '@angular/core';
import { escapeStringRegexp } from '../helpers/helper';

@Directive({
  selector: '[appColorSearchedLetters]'
})
export class ColorSearchedLettersDirective implements OnInit {
  @Input() search: string;
  @Input() text: string;
  @Input() classToApply: string;

  constructor(private el: ElementRef, private renderer: Renderer) { }

  ngOnInit() {
    if (typeof this.classToApply === 'undefined') {
      this.classToApply = '';
    }

    if (typeof this.search === 'undefined') {
      this.renderer.setElementProperty(this.el.nativeElement, 'innerHTML', this.text);
      return;
    }

    let search = escapeStringRegexp(this.search.toString());
    this.renderer.setElementProperty(this.el.nativeElement, 'innerHTML', this.replace(this.text, search));
  }

  replace(txt: string, search: string) {
    let searchRgx = new RegExp('('+search+')', 'gi');

    return txt.replace(searchRgx, `<span class="${this.classToApply}">$1</span>`);
  }
}

帮手

import { escapeStringRegexp } from '../helpers/helper';

包含:

let matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;

export function escapeStringRegexp (str) {
  if (typeof str !== 'string') {
    throw new TypeError('Expected a string');
  }

  return str.replace(matchOperatorsRe, '\\$&');
};

此功能来自https://www.npmjs.com/package/escape-string-regexp,功劳归属于Sindresorhus。

以下是我如何使用它:

<span appColorSearchedLetters [search]="search" [text]="user.name" classToApply="searched"></span>