如何将 DOM 附加到 Angular 2 组件并仍然获得封装样式
Posted
技术标签:
【中文标题】如何将 DOM 附加到 Angular 2 组件并仍然获得封装样式【英文标题】:How do I append DOM to an Angular 2 component and still get encapsulated styles 【发布时间】:2017-02-19 01:46:37 【问题描述】:我正在升级现有的 Angular 2 应用程序,该应用程序广泛使用 JQuery 插件、D3 甚至一些 React 组件(所有这些都使用 sizzle,所以我很确定它适用于所有组件)。由于一次重写所有这些确实没有意义,我试图将其中一些包装在 Angular 2 组件中。为了向您展示我的意思,我有一个简单的组件,它使用 Jquery 将项目添加到 DOM...
import Component, AfterViewInit, ElementRef from '@angular/core';
declare var $:JQueryStatic;
@Component(
selector: 'px-spinner',
template: String(require('./spinner.template')),
styles: [require('!raw!stylus-loader!./spinner.styles')]
)
export class SpinnerComponent implements AfterViewInit
constructor(public el:ElementRef)
ngAfterViewInit()
$(this.el.nativeElement).append("<div class='output'>Output 2</div>")
这里的问题是样式没有应用于输出 2。当我查看 DOM 时,原因变得很明显......
<ng-spinner class="ng-scope" id="NG2_UPGRADE_0_pxSpinner_c0" _nghost-ylc-1="">
<div _ngcontent-ylc-1="" class="start">
<div _ngcontent-ylc-1="" class="output">output 1</div>
</div>
<div class="output">Output 2</div>
</ng-spinner>
JQuery 添加的 DOM 元素缺少 _ngcontent-ylc-1=""
。有没有办法让 Ng2 在 JQuery 注入 DOM 时添加这个?
更新
这个问题与这个问题(Angular2 - adding [_ngcontent-mav-x] to styles)类似,但我想问题是如何将注入的 dom 包含在 ViewEncapsulation 中?
【问题讨论】:
【参考方案1】:如果你使用像
这样的风格:host .output
...
它应该被应用。
如果这不起作用,请使用
:host /deep/ .output
...
【讨论】:
这只会使其全局正确吗?我想保留 ViewEncapsulation 更新以反映我仍然希望它与封装在组件中的 DOM 隔离。 你不能在 ViewEncapsulation 中包含被感染的 DOM。仿真是在构建时(使用 AOT)或创建组件时计算的。不过,可能可行的是从组件宿主元素中读取_ngcontent-ylc-1
属性并将其也应用于注入的html。 /deep/
不会使样式全局化,但选择器会被重写,这样子组件也会被寻址。
感谢 Gunter 的澄清,我会尝试并回复您!
Host 是一个匹配当前元素的选择器。使用:host xxx
或:host /deep/ xxx
,所有匹配xxx
的后代元素都会被寻址。【参考方案2】:
我认为您可以从 nativeElement 获取 ngAfterViewInit 中的 _ngcontent-ylc-1 属性。然后将此属性应用于您附加的 html。
【讨论】:
我试图避免这种类型的 hacky 修复,但它可能是某些人目前唯一的选择。 是的,这是个糟糕的选择。最好的解决方案是以有角度的方式重写它。以上是关于如何将 DOM 附加到 Angular 2 组件并仍然获得封装样式的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Angular 2 的指令中附加动态 DOM 元素?
如何在 Angular 组件 HTML DOM 中注入 SVG 图标精灵?