如何在Angular主/细节可折叠表格的详细部分中插入富文本?

huangapple go评论72阅读模式
英文:

How to put rich text in the detail section of angular master/detail collapsible table?

问题

我有一个Angular主/细节可折叠表格,如下所示:
如何在Angular主/细节可折叠表格的详细部分中插入富文本?

请注意,细节部分的文本是一个大段落。我希望它是格式化的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:
如何在Angular主/细节可折叠表格的详细部分中插入富文本?

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:

&lt;dx-data-grid
  id=&quot;gridContainer&quot;
  [dataSource]=&quot;nutrients&quot;
  [showBorders]=true
&gt;&gt;
  &lt;dxo-scrolling mode=&quot;infinite&quot;&gt;&lt;/dxo-scrolling&gt;
  &lt;dxo-paging [enabled]=&quot;false&quot;&gt;&lt;/dxo-paging&gt;
  &lt;dxi-column dataField=&quot;name&quot;&gt;Name&lt;/dxi-column&gt;
  &lt;dxi-column dataField=&quot;unitName&quot;&gt;Unit Name&lt;/dxi-column&gt;
  &lt;dxi-column dataField=&quot;rda&quot;&gt;RDA&lt;/dxi-column&gt;
  &lt;dxo-master-detail [enabled]=&quot;true&quot; template=&quot;detail&quot;&gt;&lt;/dxo-master-detail&gt;

  &lt;div class=&quot;info&quot; *dxTemplate=&quot;let nutrient of &#39;detail&#39;; let i = index;&quot;&gt;
    {{ nutrient.data.info }}
  &lt;/div&gt;
&lt;/dx-data-grid&gt;

The associated detail text in the database is not formatted. If I try to add tags, like &lt;p&gt; 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:

&lt;div *ngFor=&quot;let htmlInsertionContent of htmlInsertionContents; let index = index&quot;&gt;
  &lt;div [innerHTML]=&quot;htmlInsertionContent&quot; &gt;&lt;/div&gt;
&lt;/div&gt;

ts:

import { Component, OnInit } from &#39;@angular/core&#39;;
import { DomSanitizer, SafeHtml } from &#39;@angular/platform-browser&#39;;
import { Observable } from &#39;rxjs&#39;;

@Component({
  selector: &#39;app-test&#39;,
  templateUrl: &#39;./test.component.html&#39;,
  styleUrls: [&#39;./test.component.scss&#39;],
})
export class TestComponent implements OnInit{
  htmlInsertionContents: SafeHtml[]= [];

  constructor(private sanitizer: DomSanitizer) {
  }

  ngOnInit(): void {
    this.asyncData().subscribe((value) =&gt; {
      value.forEach(v=&gt;{
        this.htmlInsertionContents.push(this.sanitizer.bypassSecurityTrustHtml(`&lt;h1&gt;header tag&lt;/h1&gt;&lt;hr&gt;&lt;hr&gt;&lt;p&gt;${this.getRandomNumberString()}&lt;/p&gt;`))
      })
    })
  }

  asyncData(): Observable&lt;number[]&gt; {
    return new Observable(observer =&gt; {
      setTimeout(()=&gt;{
        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:

&lt;ng-container *ngFor=&quot;let text of textArray; let index = index&quot;&gt;
  &lt;div [innerHTML]=&quot;convertIntoSafeHTML(text)&quot; &gt;&lt;/div&gt;
&lt;/ng-container&gt;

ts:

import { Component } from &#39;@angular/core&#39;;
import { DomSanitizer, SafeHtml } from &#39;@angular/platform-browser&#39;;

@Component({
  selector: &#39;app-test&#39;,
  templateUrl: &#39;./test.component.html&#39;,
  styleUrls: [&#39;./test.component.scss&#39;],
})
export class TestComponent {

  textArray: string[]= [
    `&lt;h1&gt;header tag&lt;/h1&gt;&lt;hr&gt;&lt;hr&gt;&lt;p&gt;${this.getRandomNumberString()}&lt;/p&gt;`,
    `&lt;h1&gt;header tag&lt;/h1&gt;&lt;hr&gt;&lt;hr&gt;&lt;p&gt;${this.getRandomNumberString()}&lt;/p&gt;`,
    `&lt;h1&gt;header tag&lt;/h1&gt;&lt;hr&gt;&lt;hr&gt;&lt;p&gt;${this.getRandomNumberString()}&lt;/p&gt;`,
    `&lt;h1&gt;header tag&lt;/h1&gt;&lt;hr&gt;&lt;hr&gt;&lt;p&gt;${this.getRandomNumberString()}&lt;/p&gt;`,
  ]

  constructor(private sanitizer: DomSanitizer) {
  }

  getRandomNumberString(): string {
    return Math.random().toString()
  }

  convertIntoSafeHTML(htmlAsString: string): SafeHtml {
    return this.sanitizer.bypassSecurityTrustHtml(htmlAsString)
  }
}

答案3

得分: 0

解决方案很简单,正如我所想的那样。只需使用

&lt;div class=&quot;info&quot; *dxTemplate=&quot;let nutrient of &#39;detail&#39;;&quot; [innerHtml]=&quot;nutrient.data.info&quot;&gt;
&lt;/div&gt;

[innerHtml] 指令是关键。

英文:

The solution was simple, as I thought it had to be. Simply use

&lt;div class=&quot;info&quot; *dxTemplate=&quot;let nutrient of &#39;detail&#39;;&quot; [innerHtml]=&quot;nutrient.data.info&quot;&gt;
&lt;/div&gt;

The [innerHtml] directive was the key.

huangapple
  • 本文由 发表于 2023年5月29日 23:17:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76358486.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定