注意:我在Angular 5和Angular 6中都尝试了这个例子。


如果在Angular组件上使用'封装:ViewEncapsulation.None'
,< style>
元素将附加到< head>
何时显示组件。即使在组件被销毁之后,< style>
元素也永远不会被删除。这是问题。
随着显示的组件越来越多,< head>
中有越来越多的< style>
元素。最终,当存在相同html元素的全局css规则时,这会导致冲突,例如 body
,根据我的例子。只使用最后附加的< style>
块中的CSS,即使最后< style>
块属于不再存在的组件。 / p>


我希望看到一个合适的解决方案,以便从DOM与某些组件一起出现的< style>
元素。例如。当触发组件中的 onDestoy
函数时清理。
我是Angular的新手,我刚刚偶然发现了这个有趣的行为。很高兴知道是否有一个简单的解决方法。


示例:
 https://stackblitz.com/edit/angular-ukkecu


 

在我的应用程序中,我有3个包装组件,将是我的应用程序的根元素。当时只会显示一个。显示的组件将确定整个网站的主题。它应该包括全局样式,更具体地说是全局样式(主题)的专用变体。出于这个原因,他们都有'封装:ViewEncapsulation.None'
。每种全局样式都有自己编译的bootstrap变体和其他基于SASS变量的外部插件。因此,在这里进行封装是没有选择的,这些是全局样式和插件。
解决方案只在第一次正常工作,直到显示其他组件并且< style>
元素附加到< head>
。之后,仅使用最后使用的组件中的样式,因为它的< style>
排在最后并覆盖以前的任何样式。
似乎唯一的解决方案是重新加载页面,或者不使用组件来切换全局主题。

答案 0 :(得分:4)
忘记您的情况encapsulation
,这对您的要求无济于事。取而代之的是使用共享服务,将其称为 style-service ,它将在文档头中添加/删除样式节点。
您无需在stylesUrls
装饰器的@Component
中添加CSS样式,而是使用ngOnInit
函数上的 style-service 来添加样式,这会将样式节点添加到文档头。使用ngOnDestroy
函数销毁组件后,您将使用 style-service 删除样式,这将从文档头删除样式节点。
足够了,让我们看一些代码:
style.service.ts
import { Injectable } from '@angular/core';
@Injectable()
export class StyleService {
private stylesMap: Map<any, Node> = new Map();
private host: Node;
constructor() {
this.host = document.head;
}
private createStyleNode(content: string): Node {
const styleEl = document.createElement('style');
styleEl.textContent = content;
return styleEl;
}
addStyle(key: any, style: string): void {
const styleEl = this.createStyleNode(style);
this.stylesMap.set(key, styleEl);
this.host.appendChild(styleEl);
}
removeStyle(key: any): void {
const styleEl = this.stylesMap.get(key);
if (styleEl) {
this.stylesMap.delete(key);
this.host.removeChild(styleEl);
}
}
}
WrapperVariantRedComponent (来自您的演示)
import { Component, OnInit, OnDestroy, Renderer2 } from '@angular/core';
import { StyleService } from '../style.service';
declare const require: any;
@Component({
selector: 'app-wrapper-variant-red',
templateUrl: './wrapper-variant-red.component.html',
styleUrls: [ './wrapper-variant-red.component.css']
})
export class WrapperVariantRedComponent implements OnInit, OnDestroy {
constructor(private styleService: StyleService) { }
ngOnInit() {
this.styleService.addStyle('red-theme', require('../../theme/global-theme-variant-red.css'));
}
ngOnDestroy() {
this.styleService.removeStyle('red-theme');
}
}
从StackBlitz示例中工作(派生)DEMO。
答案 1 :(得分:0)
不知道解决方案,但您正在使用它的组件的ViewEncapsulation.NONE属性不是默认属性默认值是ViewEncapsulation.Emulated我想它为组件中的每个标记提供唯一ID因此解决了这些类型的问题然后你为什么使用ViewEncapsulation.NONE ???