gpt4 book ai didi

Angular - 如何在组件被销毁后从 中删除 <style> 元素

转载 作者:太空狗 更新时间:2023-10-29 17:07:43 31 4
gpt4 key购买 nike

Note: I tried the example in both Angular 5 and Angular 6.

问题

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

head styles

我希望看到从 DOM 中删除 <style> 的合适解决方案与某些组件一起出现的元素。例如。在 onDestoy 时清理来自组件的功能被触发。

我是 Angular 的新手,我刚刚偶然发现了这个有趣的行为。很高兴知道是否有简单的解决方法。


例子

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

Angular example

在我的应用程序中,我有 3 个包装器组件,它们将成为我的应用程序的根元素。当时只会显示一个。显示的组件将决定整个网站的主题。它应该包括全局样式,更具体地说是全局样式(主题)的专用变体。出于这个原因,他们都有 'encapsulation: ViewEncapsulation.None' .每个全局样式都有自己编译的 Bootstrap 变体和其他基于 SASS 变量的外部插件。所以在这里封装是没有选择的,这些是全局样式和插件。

只有在显示其他组件和 <style> 之前,该解决方案第一次工作正常元素附加到 <head> .之后只会使用最后使用的组件的样式,因为它的 <style>排在最后并覆盖任何以前的样式。


可能的解决方案

似乎唯一的解决办法是重新加载页面,或者不使用组件来切换全局主题。

最佳答案

在你的情况下忘记 encapsulation ,它不能帮助你满足你的要求。取而代之的是使用共享服务,我们称它为 style-service,它将在文档头部添加/删除样式节点。

不是在 @Component 装饰器的 stylesUrls 中添加您的 css 样式,而是使用 style-service 添加它们ngOnInit 函数,它将样式节点添加到文档头部。一旦组件在 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');
}

}

工作( fork )DEMO来自您的 StackBlitz 示例。

关于Angular - 如何在组件被销毁后从 <head> 中删除 &lt;style&gt; 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50311141/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com