注意:我在Angular 5和Angular 6中都尝试了这个例子.
如果'encapsulation: ViewEncapsulation.None'在Angular组件上使用,则<style>元素将附加到<head>何时显示组件.<style>即使在组件被销毁之后,该元素也永远不会被删除.这是问题所在.随着展示的组件越来越多,其中的<style>元素越来越多<head>.最终,当存在针对相同html元素的全局css规则时,这会导致冲突,例如body,根据我的示例.<style> 即使最后一个<style>块属于不再存在的组件,也只使用最后附加的块中的CSS .
我想看到一个适当的解决方案,从DOM中删除<style>一些组件附带的元素.例如,当onDestoy触发组件的功能时进行清理.
我是Angular的新手,我偶然发现了这个有趣的行为.很高兴知道是否有一个简单的解决方法.
示例:https: //stackblitz.com/edit/angular-ukkecu
在我的应用程序中,我有3个包装器组件,它们将是我的应用程序的根元素.当时只会显示一个.显示的组件将确定整个网站的主题.它应该包括全局样式,更具体地说是全局样式(主题)的专用变体.因此他们都有'encapsulation: ViewEncapsulation.None'.每种全局样式都有自己编译的bootstrap变体和其他基于SASS变量的外部插件.因此,在这里进行封装是没有选择的,这些是全局样式和插件.
该解决方案仅在第一次正常工作,直到显示其他组件并将<style>元素附加到<head>.之后,仅使用最后使用的组件中的样式,因为它<style>最后一个并覆盖任何以前的样式.
似乎唯一的解决方案是重新加载页面,或者不使用组件来切换全局主题.
ben*_*oam 13
忘记encapsulation您的情况,它无法帮助您满足您的要求。而是使用共享服务,我们称之为style-service,它将添加/删除文档头中的样式节点。
您将使用style-service on函数添加样式,而不是stylesUrls在@Component装饰器的 中添加您的 css 样式,这会将样式节点添加到文档头部。一旦组件在功能上被破坏,您将使用style-service删除样式,这将从文档头中删除样式节点。ngOnInitngOnDestroy
话不多说,让我们看一些代码:
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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
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');
}
}
Run Code Online (Sandbox Code Playgroud)
来自您的 StackBlitz 示例的工作(分叉)演示。
| 归档时间: |
|
| 查看次数: |
1828 次 |
| 最近记录: |