【问题标题】:Bootstrap Accordion example not working with Angular 4 [innerHTML]Bootstrap Accordion 示例不适用于 Angular 4 [innerHTML]
【发布时间】:2018-03-05 01:11:52
【问题描述】:

我正在尝试在我的 Angular 4 应用中实现 Bootstrap Accordion 示例

<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
<div class="panel panel-default">
    <div class="panel-heading" role="tab" id="headingOne">
        <h4 class="panel-title">
            <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
                Collapsible Group Item #1
            </a>
        </h4>
    </div>
    <div id="collapseOne" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingOne">
        <div class="panel-body">
            Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
        </div>
    </div>
</div>
<div class="panel panel-default">
    <div class="panel-heading" role="tab" id="headingTwo">
        <h4 class="panel-title">
            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
                Collapsible Group Item #2
            </a>
        </h4>
    </div>
    <div id="collapseTwo" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingTwo">
        <div class="panel-body">
            Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
        </div>
    </div>
</div>
<div class="panel panel-default">
    <div class="panel-heading" role="tab" id="headingThree">
        <h4 class="panel-title">
            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
                Collapsible Group Item #3
            </a>
        </h4>
    </div>
    <div id="collapseThree" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingThree">
        <div class="panel-body">
            Anim pariatur cliche reprehenderit, enim eiusmod high life accusamus terry richardson ad squid. 3 wolf moon officia aute, non cupidatat skateboard dolor brunch. Food truck quinoa nesciunt laborum eiusmod. Brunch 3 wolf moon tempor, sunt aliqua put a bird on it squid single-origin coffee nulla assumenda shoreditch et. Nihil anim keffiyeh helvetica, craft beer labore wes anderson cred nesciunt sapiente ea proident. Ad vegan excepteur butcher vice lomo. Leggings occaecat craft beer farm-to-table, raw denim aesthetic synth nesciunt you probably haven't heard of them accusamus labore sustainable VHS.
        </div>
    </div>
</div>

当我将此代码直接放在我的 html 文件中时,它就像一个魅力,但是当我尝试在我的 html 文件中动态地传递此代码为 [innerHTML] 时,它不起作用。

我在开发工具中检查过,发现在后者的情况下,锚标签只有

<a class="collapsed" role="button" href="#collapseOne">

而不是

&lt;a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseOne" aria-expanded="true" aria-controls="collapseOne"&gt;

我也认为它与ViewEncapsulation.None 无关,因为我已经尝试过了,但没有帮助。我也试过用@ng-bootstrap/ng-bootstrap

我是 Angular 的新手,想了解我缺少什么?非常感谢任何帮助。

【问题讨论】:

  • 请注意拼写为[innerHTML]
  • 感谢@ConnorsFan。更新了拼写更正的问题。
  • 我认为更新到[innerHTML] 并没有神奇地解决您的问题?
  • @Zze 不,显然,角度不适用于 [innerHtml] 以及
  • 我已经解决了,现在正在为您解答。

标签: angular twitter-bootstrap-3 innerhtml


【解决方案1】:

当您通过 [innerHtml][src] 等绑定手动将内容注入 DOM 时,默认情况下,Angular 将尝试保护您的用户免受安全风险/跨站点脚本安全漏洞的影响

[The] DomSanitizer 通过清理值以确保在不同的 DOM 上下文中安全使用,有助于防止跨站点脚本安全漏洞 (XSS)。

例如,当在超链接中绑定 URL 时, someValue 将被清理,以便攻击者无法注入例如一个 javascript: 将在网站上执行代码的 URL。

在特定情况下,可能需要禁用清理功能,例如,如果应用程序确实需要生成其中包含动态值的 javascript: 样式链接。用户可以通过使用 bypassSecurityTrust... 方法之一构造一个值,然后从模板绑定到该值来绕过安全性。

https://angular.io/api/platform-browser/DomSanitizer

这句话中的粗体正是我们为了实现这一点需要在这里做的。

这是一个working example,它使用 DOMSanitizer 绕过注入的 html 的清理过程。

例子的关键在这里:

// inject the DomSanitizer
constructor(private _sanitizer: DomSanitizer){}
// bypass the sanitizer 
public get htmlProperty() : SafeHtml {
   return this._sanitizer.bypassSecurityTrustHtml(this._htmlProperty);
}

this._htmlProperty 是您在问题中以字符串形式存在的大量 html。


注意:对于刚赶上 Angular 潮流的人来说,这是一个经典的陷阱。整个消毒过程对安全性很有好处,但它是我最不喜欢的角度功能,因为必须实现它是一个持续的烦恼。

附加说明: 考虑是否应将您的具体实现拆分为自己的 component,然后可以稍后以如下形式引用:&lt;app-bootstrap-accordion [data]="accordionData"&gt;&lt;/app-bootstrap-accordion&gt; 其中accordionData 是包含一组面板数据的对象,它将生成一个动态手风琴。

【讨论】:

  • 我将示例更新为现在只包含 1 个手风琴。
  • @CodeWarrior 我个人尽量保持我的[innerHtml] 绑定/注入尽可能低,这不是真正的“角度”方式 - 但很多来自 jquery 背景的人喜欢使用它。 (请参阅我在答案中的附加说明)。很高兴我能帮忙:)
  • 我听取了您的建议并制作了一个新组件,它工作得很好,但是当我按照以前的方式进行操作时,它在屏幕上给了我这个消息 安全值必须使用属性 =binding。我将经过清理的 HTML 作为属性绑定传递,然后为什么这个消息和它出现在我的屏幕上,我有手风琴,即在 UI 上。
  • @CodeWarrior 我不完全确定我理解你的问题,你可能需要发布一个带有代码等的新问题来澄清......但是这是我如何实现手风琴的一个例子在它自己的组件中:stackblitz.com/edit/… - 让我知道。
  • &lt;li *ngFor="let item of array"&gt; &lt;div [innerHtml]="item.accordioncontent"&gt;&lt;/div&gt; &lt;/li&gt; 这是我在 html 和 .ts 文件中的代码,我正在循环数组,并根据我正在执行此操作的条件array[i].accordioncontent = this._sanitizer.bypassSecurityTrustHtml(array[i].accordioncontent )@Zze Lemme 知道是否这仍然不清楚并发布一个新问题
【解决方案2】:

您可以使用[attr.data-parent]="'#bs-collapse_'+index",其中 index 是一个变量。

【讨论】: