头部重复的样式和许多<style>元素

mcm*_*hfy 23 html javascript angular-material2 angular

我对angular-material2组件非常满意,但有一些我不理解的奇怪行为,并且他们没有适当的文档,特别是对于丰富和定制他们的组件.

我的项目看起来像:

.src
  --app
    --components
      --login-component
           login-component.html
           login-component.scss
           login-component.js
      --login-component
            home-component.html
            home-component.scss
            home-component.js
       --and so on ...
    app.component.html
    app.component.scss
    app.component.ts
    app.module.ts
    app.routing.ts
    --assets
    --environments
    --scss
      styles.scss
      _material2-theme.scss
      _variables-scss
      _utilities.scss
      _reset.scss
   favicon
   index.html
   and so on ....
Run Code Online (Sandbox Code Playgroud)

在angular-cli.json中,我修改了样式以查看scss/style.scss

...
"styles": [
        "scss/styles.scss"
      ]
...
Run Code Online (Sandbox Code Playgroud)

_material2-theme.scss看起来像:

//////////////////////* THEMES */ Custom Blue Theme*/
@import '~@angular/material/theming';
@include mat-core();
$app-primary: mat-palette($mat-light-blue);
$app-accent:  mat-palette($mat-light-blue, A200, A100, A400);
$app-theme:   mat-light-theme($app-primary, $app-accent);
@include angular-material-theme($app-theme);

/*default palette forground/background*/
$light-foreground-palette: map-get($app-theme, foreground);
$light-background-palette: map-get($app-theme, background);

$primary: map-get($app-theme, primary);
$accent: map-get($app-theme, accent);
Run Code Online (Sandbox Code Playgroud)

在style.scss中我正在导入要用scss cli编译器编译的所有内容

//////////////////////* CUSTOM */
@import "_material2-theme.scss";
@import "_reset.scss";
@import "_utilities.scss";
 //////////////////////* COMPONENTS */
 @import "~app/components/login/login.component.scss";
Run Code Online (Sandbox Code Playgroud)

我的问题是在scss编译之后我们在html头中有很多样式标签,其中一些是重复的,看起来像:

在此输入图像描述

似乎所有东西都编译成一个在head中添加的样式(一个具有type属性的样式),之后每个scss组件在每个css组件中分开,其中单独的样式在head中,这非常奇怪.我做错了什么或只是方式是工作材料2?

Max*_*kyi 5

您看到的行为是由ViewEncapsulation.Emulated为材料组件定义的.

首先,您不需要将组件的样式添加到全局样式"scss/styles.scss":

//////////////////////* COMPONENTS */
@import "~app/components/login/login.component.scss";
Run Code Online (Sandbox Code Playgroud)

如果你这样做,除了你的样式被复制之外,你将失去样式封装,因为添加的样式components/login/login.component.scss将变为全局.

现在,问题为什么有很多style元素.当您使用ViewEncapsulation.Emulated它并且它是默认视图封装模式时,Angular会将每个组件的样式放入其自己的style标记中,并将属性添加到组件模板内的元素.在材料中,所有组件都使用模拟封装模式,因此对于每个组件style添加标签.

如果您@Component({..., encapsulation: ViewEncapsulation.Native })为组件添加,您将看到style将删除组件.

以下是添加style标记的逻辑:

export class DomSharedStylesHost extends SharedStylesHost implements OnDestroy {
  ...
  private _addStylesToHost(styles: Set<string>, host: Node): void {
    styles.forEach((style: string) => {
      const styleEl = this._doc.createElement('style');  <--- creates a style element
      styleEl.textContent = style;
      this._styleNodes.add(host.appendChild(styleEl));
    });
  }
Run Code Online (Sandbox Code Playgroud)