将html标签附加到完整句子中的选定单词2

时间:2017-09-21 17:08:27

标签: javascript html angular

我有一个组件,它接收JSON对象中的句子,每个句子都带有一个与不同颜色相关联的单词数组。

以下是组件的片段

    export class ExampleComponent implements OnInit, OnDestroy {

      ngOnInit() {this._getChats(userId);}

      private _getData(userId: string)  {
        this.dataSub = this.api
         .getDataList$()
         .subscribe(
           res => {
             this.data = res.result.data;
          },
          error => {
           console.log(error);
         });
      }
    }

我得到的数据如下:

[{
   "message": "Attention! The user already exists.",
   "words": [
    {"word": "user", "color": "#ffddcc"},
    {"word": "Attention!", "color": "#ff99cc"},
    {"word": "exists", "color": "#cddcef"}
   ]
 },
 {"message": "Hey! There are no users",
  "words": [{"word": "users","color": "#ffddcc"},{"word": "Hey!","color": "#ff99cc"},{"word": "are","color": "#cddcef"}]},
 {"message": "This is a are recipe","words": [{"word": "are","color": "#ffddcc"},{"word": "recipe","color": "#cddcef"}]}
]

等等。 现在我正在我的html中显示这些句子如下

 <div *ngFor="let dt of data">{{dt.message | formatData:dt.words}}</div>

我的问题是我想用下面各个颜色代码的span标签替换数组中提到的所有单词

 <div><span style="color:#ff99cc">Attention!</span> The <span style="color:#ffddcc">user</span> already <span style="color:#cddcef">exists</span>.

我尝试创建一个自定义管道来识别和替换字符串。但我被困在这里。

以下是我写的自定义管道。

   export class FormatDataPipe implements PipeTransform {
     transform(value: string, args: any) {
       if(args.length === 0) {
         return value;
       }
       for(let i =0; i < args.length; i++) {
         if(value.includes(args[i].word)) {
           const subVal = `<span style='color:'"` + args[i].color + `"'>` + args[i].token + `</span>`;
           value.replace(args[i].token, subVal);
         }
       }
    }
  }

先谢谢。

2 个答案:

答案 0 :(得分:1)

您的管道需要使用DomSanitizer,以便它可以将html注入您的字符串之前的位置。然后你的管道可以用html span标签中包含的单词替换字符串中单词的所有实例。

你的新烟斗:

import { DomSanitizer } from '@angular/platform-browser';

...

@Pipe({
  name: 'formatData'
})
export class FormatDataPipe implements PipeTransform {
  constructor(private domSanitizer: DomSanitizer) {}

  transform(message: string, words: any) {
    let htmlString = words.reduce(
        (memo, word) => memo.replace(
          word.word, 
          `<span style="color:${word.color};">${word.word}</span>`
        ),
        message);

    return this.domSanitizer.bypassSecurityTrustHtml(htmlString);
 }
}

管道的Html实现:

<div *ngFor="let dt of data" [innerHtml]="dt.message | formatData: dt.words"></div>

答案 1 :(得分:0)

我说,将句子转换为单词数组运行内部循环来渲染它们。

<div *ngFor="let dt of data">
  <span *ngFor="let wd of words(dt.message)" style="color:#ffddcc">{{wd.text}}</span>
</div>

在你的组件中会有一个方法,它将采用sentense并转换并返回数组/对象或单词

words(snts: string) {
 return snts.split('');
}