2016-04-29 60 views
8

我在角1.x中做到了這一點,但我想知道如何使用關鍵字如何突出角2中的段落中的單詞?

 <td><div highlight="var" keywords="somename">  {{paragraph}}</div></td> 
以突出角2..in角1.x的IAM動態字

我已經做了上面的HTML使用下面的angular-highlight.js。

 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: '=' 
    } 
}; 
}); 

回答

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> 
+0

是否被angular2 +推薦直接操作'innerHTML'? –

+0

不是直接通過'renderer' – Maxime

9

我想創建一個自定義的指令,這個:

@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(在模擬one - default on)添加屬性以便能夠看到應用的樣式:

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

+0

​​

{{key.name}}
Arron

+0

如果你想引用關鍵字陣列,使用相當的語法如下:'

{{key.name}}
'。否則'關鍵字'將被視爲一個字符串;-) –

+1

但上面的代碼沒有綁定key.name ...它顯示了一個空白空間.. – Arron

相關問題