在 Angular 中,我如何动态地将某些单词包装在另一个 html 元素中?
In Angular how do I dynamically wrap certain words in another html element?
我有这个简单的 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."
在这种情况下,Angular 生成的 HTML 本质上等同于:
<p>If you want my body and you think I'm sexy, come on, sugar, tell me so.</p>
我将如何修改 MyComponent
以便它检测 someString
中出现的单词 sexy
并让 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 组件而不是原生 HTML 元素中怎么办?这是否需要采用不同的方法?
你可以试试这个: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>');
}
}
您可以使用类似下面的内容 - 其中在呈现主句后,您可以用 span 元素替换特殊词并应用 CSS class,比如 .special
到那个跨度标签。
从“@angular/core”导入{组件、输入、ElementRef、AfterViewInit};
@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>`);
}
}
为了让您的代码通用,您可以使用额外的 @Input()
作为特殊词。
在您的应用程序的 styles.scss
中,您可以定义 CSS class .special
.
.special {
font-weight: bold;
}
如果您想知道为什么不能使用类似的逻辑将 sentence
的内容替换为如下内容:
this.sentence = this.sentence.replace(new RegExp(`${this.specialWord}`, 'g'),
`<span class="special">${this.specialWord}</span>`);
然后,请注意 Angular 将转义 HTML 标签,它们将按原样出现在输出中。所以你会在浏览器中看到类似这样的东西,而不是样式化的 span。
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 之后完成替换。
此解决方案避免使用 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');
}
}
我有这个简单的 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."
在这种情况下,Angular 生成的 HTML 本质上等同于:
<p>If you want my body and you think I'm sexy, come on, sugar, tell me so.</p>
我将如何修改 MyComponent
以便它检测 someString
中出现的单词 sexy
并让 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 组件而不是原生 HTML 元素中怎么办?这是否需要采用不同的方法?
你可以试试这个: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>');
}
}
您可以使用类似下面的内容 - 其中在呈现主句后,您可以用 span 元素替换特殊词并应用 CSS class,比如 .special
到那个跨度标签。
从“@angular/core”导入{组件、输入、ElementRef、AfterViewInit};
@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>`);
}
}
为了让您的代码通用,您可以使用额外的 @Input()
作为特殊词。
在您的应用程序的 styles.scss
中,您可以定义 CSS class .special
.
.special {
font-weight: bold;
}
如果您想知道为什么不能使用类似的逻辑将 sentence
的内容替换为如下内容:
this.sentence = this.sentence.replace(new RegExp(`${this.specialWord}`, 'g'),
`<span class="special">${this.specialWord}</span>`);
然后,请注意 Angular 将转义 HTML 标签,它们将按原样出现在输出中。所以你会在浏览器中看到类似这样的东西,而不是样式化的 span。
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 之后完成替换。
此解决方案避免使用 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');
}
}