Com*_*ple 1 typescript angular-material angular
我正在从事个人 Angular 项目(使用 Angular Material),但找不到此问题的解决方案。
例如,我有一个长文本,如下所示:
当你采取闪避动作时,你完全专注于避免攻击。在你的下一个回合开始之前,如果你能看到攻击者,那么对你进行的任何攻击检定都会处于劣势,并且你的敏捷豁免检定具有优势。如果您丧失行为能力(如条件中所述)或您的速度降至 0,您将失去此福利。
我有一些关键词,这里是缺点,优点是无能力。我想将字体设置为粗体并添加一个工具提示来为每个关键字添加一个小解释。
我用管道将字体加粗没有问题,但我找不到为关键字添加工具提示的解决方案。使用innerHTML不起作用,这是我当前的解决方案:
<div innerHTML="description | transformKeyWord"></div>
Run Code Online (Sandbox Code Playgroud)
还有我的烟斗:
transform(value: string, ...args: unknown[]): unknown {
let result = value
result = result.replace('advantage', '<span matTooltip="Advantage description">advantage</span>')
result = result.replace('incapacitated', '<b [matTooltip]="Incapacitated description">incapacitated</b>')
return result;
}
Run Code Online (Sandbox Code Playgroud)
我认为这不是使用带有innerHTML的管道的好解决方案,这就是我寻求帮助的原因。
TLDR: https://stackblitz.com/edit/angular-ivy-86uxvs? file=src/app/app.component.html
在我看来,每个关键字都是一个object带有 aword和 atooltip的。所以我将为此定义架构。
export type keyword = {
word: string;
tooltip: string;
};
Run Code Online (Sandbox Code Playgroud)
我将在对象中定义关键字以便于查找:
keywords: { [key: string]: keyword } = {
disadvantage: {
word: 'disadvantage',
tooltip: 'advantage description',
},
incapacitated: {
word: 'incapacitated',
tooltip: 'incapacitated description',
},
};
Run Code Online (Sandbox Code Playgroud)
我认为最好的方法是将字符串拆分为字符串和关键字的数组,这样我们就可以按顺序将它们打印到html中。这是一个可以做到这一点的函数 - 我将所有这些都放在一个服务中,因为它看起来很合适。
toDynamicText(text: string): (string | keyword)[] {
const res: (string | keyword)[] = [];
const tokens = text.split(' ');
let i = 0;
for (const token of tokens) {
let keyword = this.keywords[token.toLowerCase()]; //undefined if word is not a keyword
if (keyword) {
i = res.push(keyword);
} else {
if (!res[i]) res[i] = token;
else res[i] += ' ' + token;
}
}
return res;
}
Run Code Online (Sandbox Code Playgroud)
输出数组如下所示:
[
"When you take the Dodge action, you focus entirely on avoiding attacks. Until the start of your next turn, any Attack roll made against you has",
{
"word": "disadvantage",
"tooltip": "advantage description"
},
"if you can see the attacker, and you make Dexterity Saving Throws with advantage. You lose this benefit if you are",
{
"word": "incapacitated",
"tooltip": "incapacitated description"
},
"(as explained in Conditions ) or if your speed drops to 0. "
]
Run Code Online (Sandbox Code Playgroud)
这是如何使用它的示例:
text =
'When you take the Dodge action, you focus entirely on avoiding attacks. ' +
'Until the start of your next turn, any Attack roll made against you has disadvantage if you can see the attacker, ' +
'and you make Dexterity Saving Throws with advantage. ' +
'You lose this benefit if you are Incapacitated (as explained in Conditions ) or if your speed drops to 0. ';
dynamicText: (string | keyword)[] = [];
constructor(private dynamicTextService: DynamicTextService) {}
ngOnInit(): void {
this.dynamicText = this.dynamicTextService.toDynamicText(this.text);
}
isString(token: any) {
return typeof token === 'string';
}
//Typescript compiler wants a typecast, so we have two helper functions
getTooltip(token: string | keyword) {
return (token as keyword).tooltip;
}
getWord(token: string | keyword) {
return (token as keyword).word;
}
Run Code Online (Sandbox Code Playgroud)
<p>
<ng-container *ngFor="let token of dynamicText">
<ng-container *ngIf="isString(token)">{{ token }}</ng-container>
<ng-container *ngIf="!isString(token)"
><b [matTooltip]="getTooltip(token)" style="cursor: pointer">
{{ getWord(token) }}
</b></ng-container
>
</ng-container>
</p>
Run Code Online (Sandbox Code Playgroud)
您可以通过在尝试返回tooltip和属性之前确保它们存在来使其更加健壮。word
text我会将其作为输入变量作为组件。
| 归档时间: |
|
| 查看次数: |
2854 次 |
| 最近记录: |