英文:
How to put rich text in the detail section of angular master/detail collapsible table?
问题
请注意,细节部分的文本是一个大段落。我希望它是格式化的HTML。需要有换行、项目符号和编号列表、字体、斜体、粗体等。
问题是主表格行数是可变的,因此它们是使用Angular的*ngFor或类似方式填充的。事实上,我正在使用一个名为DevExtreme的第三方库,但任何方法都会有相同的问题。以下是那段代码:
<dx-data-grid
id="gridContainer"
[dataSource]="nutrients"
[showBorders]=true
>>
<dxo-scrolling mode="infinite"></dxo-scrolling>
<dxo-paging [enabled]="false"></dxo-paging>
<dxi-column dataField="name">Name</dxi-column>
<dxi-column dataField="unitName">Unit Name</dxi-column>
<dxi-column dataField="rda">RDA</dxi-column>
<dxo-master-detail [enabled]="true" template="detail"></dxo-master-detail>
<div class="info" *dxTemplate="let nutrient of 'detail'; let i = index;">
{{ nutrient.data.info }}
</div>
</dx-data-grid>
数据库中的关联详细文本未经格式化。如果我尝试添加标签,比如<p>
,它们会直接显示在文本中。我认为我需要将文本存储为Markdown,但然后我不知道如何在详细部分中显示它。
我已经搜索了几个小时,但找不到解决方案。有什么想法吗?
英文:
I have an angular master/detail collapsible table, as shown below:
Notice that the text in the detail section is one big paragraph. I want for it to be formatted html instead. There need to be line breaks, bullet and numbered lists, fonts, italic, bold, etc.
The problem is that the number of master table rows are variable, so they are populated using angular *ngFor, or similar. In truth, I am using a third-party library called DevExtreme, but any method is gonna have the same problem. Here is that code:
<dx-data-grid
id="gridContainer"
[dataSource]="nutrients"
[showBorders]=true
>>
<dxo-scrolling mode="infinite"></dxo-scrolling>
<dxo-paging [enabled]="false"></dxo-paging>
<dxi-column dataField="name">Name</dxi-column>
<dxi-column dataField="unitName">Unit Name</dxi-column>
<dxi-column dataField="rda">RDA</dxi-column>
<dxo-master-detail [enabled]="true" template="detail"></dxo-master-detail>
<div class="info" *dxTemplate="let nutrient of 'detail'; let i = index;">
{{ nutrient.data.info }}
</div>
</dx-data-grid>
The associated detail text in the database is not formatted. If I try to add tags, like <p>
they show up in the text literally. I think I need to store the text as markdown but then I don't know how to display it in the detail section.
I've googled for hours but can't find a solution. Any ideas?
答案1
得分: 0
你的问题在于没有将值传递为SafeHtml。Angular具有安全机制来防止注入攻击。但如果你知道数据源是安全的,你可以通过绕过安全机制并将其设置为innerHTML来标记它为安全。
以下是正确的做法:
Html:
<div *ngFor="let htmlInsertionContent of htmlInsertionContents; let index = index">
<div [innerHTML]="htmlInsertionContent"></div>
</div>
ts:
import { Component, OnInit } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { Observable } from 'rxjs';
@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss'],
})
export class TestComponent implements OnInit{
htmlInsertionContents: SafeHtml[]= [];
constructor(private sanitizer: DomSanitizer) {
}
ngOnInit(): void {
this.asyncData().subscribe((value) => {
value.forEach(v=>{
this.htmlInsertionContents.push(this.sanitizer.bypassSecurityTrustHtml(`<h1>header tag</h1><hr><hr><p>${this.getRandomNumberString()}</p>`))
})
})
}
asyncData(): Observable<number[]> {
return new Observable(observer => {
setTimeout(()=>{
observer.next([0,0,0,0,0,0])
}, 3000)
})
}
getRandomNumberString(): string {
return Math.random().toString()
}
}
更多详细信息请查看:https://angular.io/api/platform-browser/DomSanitizer
英文:
The issue you have is that you are not passing the value as SafeHtml. Angular has a security mechanism to avoid injections. But if you know the source you can mark it as safe by byPassing it and setting it as innerHTML.
Here is the correct way to do it.
Html:
<div *ngFor="let htmlInsertionContent of htmlInsertionContents; let index = index">
<div [innerHTML]="htmlInsertionContent" ></div>
</div>
ts:
import { Component, OnInit } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { Observable } from 'rxjs';
@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss'],
})
export class TestComponent implements OnInit{
htmlInsertionContents: SafeHtml[]= [];
constructor(private sanitizer: DomSanitizer) {
}
ngOnInit(): void {
this.asyncData().subscribe((value) => {
value.forEach(v=>{
this.htmlInsertionContents.push(this.sanitizer.bypassSecurityTrustHtml(`<h1>header tag</h1><hr><hr><p>${this.getRandomNumberString()}</p>`))
})
})
}
asyncData(): Observable<number[]> {
return new Observable(observer => {
setTimeout(()=>{
observer.next([0,0,0,0,0,0])
}, 3000)
})
}
getRandomNumberString(): string {
return Math.random().toString()
}
}
More details on it: https://angular.io/api/platform-browser/DomSanitizer
答案2
得分: 0
以下是您要翻译的内容:
HTML:
<ng-container *ngFor="let text of textArray; let index = index">
<div [innerHTML]="convertIntoSafeHTML(text)"></div>
</ng-container>
ts:
import { Component } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss'],
})
export class TestComponent {
textArray: string[]= [
`<h1>header tag</h1><hr><hr><p>${this.getRandomNumberString()}</p>`,
`<h1>header tag</h1><hr><hr><p>${this.getRandomNumberString()}</p>`,
`<h1>header tag</h1><hr><hr><p>${this.getRandomNumberString()}</p>`,
`<h1>header tag</h1><hr><hr><p>${this.getRandomNumberString()}</p>`,
]
constructor(private sanitizer: DomSanitizer) {
}
getRandomNumberString(): string {
return Math.random().toString()
}
convertIntoSafeHTML(htmlAsString: string): SafeHtml {
return this.sanitizer.bypassSecurityTrustHtml(htmlAsString)
}
}
英文:
Here is another example that might be more useful.
HTML:
<ng-container *ngFor="let text of textArray; let index = index">
<div [innerHTML]="convertIntoSafeHTML(text)" ></div>
</ng-container>
ts:
import { Component } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss'],
})
export class TestComponent {
textArray: string[]= [
`<h1>header tag</h1><hr><hr><p>${this.getRandomNumberString()}</p>`,
`<h1>header tag</h1><hr><hr><p>${this.getRandomNumberString()}</p>`,
`<h1>header tag</h1><hr><hr><p>${this.getRandomNumberString()}</p>`,
`<h1>header tag</h1><hr><hr><p>${this.getRandomNumberString()}</p>`,
]
constructor(private sanitizer: DomSanitizer) {
}
getRandomNumberString(): string {
return Math.random().toString()
}
convertIntoSafeHTML(htmlAsString: string): SafeHtml {
return this.sanitizer.bypassSecurityTrustHtml(htmlAsString)
}
}
答案3
得分: 0
解决方案很简单,正如我所想的那样。只需使用
<div class="info" *dxTemplate="let nutrient of 'detail';" [innerHtml]="nutrient.data.info">
</div>
[innerHtml]
指令是关键。
英文:
The solution was simple, as I thought it had to be. Simply use
<div class="info" *dxTemplate="let nutrient of 'detail';" [innerHtml]="nutrient.data.info">
</div>
The [innerHtml]
directive was the key.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论