В Angular как мне динамически обернуть определенные слова в другой элемент html? - PullRequest
2 голосов
/ 21 февраля 2020

У меня есть этот простой Angular Компонент:

@Component({
  selector: 'my-component',
  template: '<p>{{someString}}</p>',
})
export class MyComponent  {
  @Input() someString: string;
}

someString может быть любой строкой любой длины. Например, представьте, что значение someString равно:

"If you want my body and you think I'm sexy, come on, sugar, tell me so."

. В этом случае HTML, сгенерированный Angular, по существу будет эквивалентен:

<p>If you want my body and you think I'm sexy, come on, sugar, tell me so.</p>

Как бы я изменил MyComponent, чтобы он обнаруживал каждое вхождение слова sexy в someString и имел бы Angular обертывание этого слова в другом элементе HTML, таком как <b>. Таким образом, в этом примере это будет генерировать что-то вроде:

<p>If you want my body and you think I'm <b>sexy</b>, come on, sugar, tell me so.</p>

Что если я захочу обернуть каждое вхождение слова sexy в Angular Component вместо собственного HTML Element? Это потребует другого подхода?

Ответы [ 3 ]

2 голосов
/ 21 февраля 2020

Вы можете попробовать это: D

@Component({
  selector: 'app-test',
  template: `
    <p [innerHTML]="stringFormatted()"></p>
  `,
  styles: []
})
export class TestComponent {

  someString = "If you want my body and you think I'm sexy, come on, sugar, tell me so.";

  stringFormatted() {
    return this.someString.replace(/sexy/g, '<b>sexy</b>');
  }
}
1 голос
/ 21 февраля 2020

Вы можете использовать что-то вроде ниже - где после рендеринга основного предложения вы можете заменить специальное слово элементом span и применить класс CSS, скажем .special к этому тегу span.

import {Component, Input, ElementRef, AfterViewInit} из '@ angular / core';

@Component({
  selector: 'my-component',
  template: '<p>{{sentence}}</p>'
})
export class MyComponent implements AfterViewInit {
  @Input() sentence: string;
  @Input() specialWord: string;

  constructor(private el: ElementRef) {
  }

  ngAfterViewInit() {
    this.el.nativeElement.innerHTML = this.el.nativeElement.
      innerHTML.replace(new RegExp(`${this.specialWord}`, 'g'), 
          `<span class="special">${this.specialWord}</span>`);
  }
}

Чтобы сохранить ваш код обобщенным c, вы можете использовать дополнительные @Input() для специального слова.

В styles.scss вашего приложения вы можете определить CSS класс .special.

.special {
  font-weight: bold;
}

Если вам интересно, почему вы не можете использовать аналогичные логи c для замены содержимого из sentence, как показано ниже:

    this.sentence = this.sentence.replace(new RegExp(`${this.specialWord}`, 'g'),
         `<span class="special">${this.specialWord}</span>`);

затем обратите внимание, что Angular будет экранировать теги HTML, и они будут отображаться как есть на выходе. Таким образом, вы увидите что-то подобное в браузере, вместо стилизованных интервалов.

Hello, it's a <span class="special">beautiful</span> day and I am in a very <span class="special">beautiful</span> city

Поэтому мне пришлось прибегнуть к манипулированию innerHTML, чтобы замена выполнялась после того, как Angular отрендерил Приговор DOM.

0 голосов
/ 24 февраля 2020

Это решение позволяет избежать использования innerHTML и опирается строго на Angular конструкции.

@Component({
  selector: 'my-component',
  template: `
  <p>
    <ng-container *ngFor="let segment of segments">
      <span *ngIf="!segment.shouldBeBold()">segment.text</span>
      <b *ngIf="segment.shouldBeBold()">segment.text</b>
    </ng-container>
  </p>
  `,
})
export class MyComponent  {
  @Input() someString: string;

  private wordsToBold = new Set(['sexy', 'body', 'sugar']); 

  get segments() {
    const regex = this.makeRegex();
    const segments = this.someString.split(regex);
    return segments.map(segment => {
      return { text: segment, shouldBeBold: wordsToBold.has(segment.toLowerCase()) };
    });
  }

  private makeRegex() {
    const expression = [...this.wordsToBold].join('\\b|\\b');
    return new RegExp(`(\\b${expression}\\b)+`, 'gi');
  }
}
...