如何将 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 组件并仍然获得封装样式的主要内容,如果未能解决你的问题,请参考以下文章

Angular2 - 将 div 添加到 DOM

角度 5 - 如何从 dom 中删除动态添加的组件

如何从 Angular 2 的指令中附加动态 DOM 元素?

如何在 Angular 组件 HTML DOM 中注入 SVG 图标精灵?

如何在angular2和ionic2中同时保留组件的DOM元素和模板字符串

访问附加到组件选择器的 angular 2 指令