Angular 9 (Ivy): CSS class^ 属性选择器停止使用 angular material 组件

Angular 9 (Ivy): CSS class^ attribute selectors stops working with angular material components

我目前正在将一个 Angular 项目从 v8 更新到 v9,我发现将 CSS class 属性与 Angular Material 组件一起使用时会出现问题。 我也更新到 Material v9.

有了这个简化的 HTML,

// Example List 1
<mat-nav-list class="example-list-1">
  <mat-list-item> SOME HTML.. </mat-list-item>
</mat-nav-list>

// Example List 2
<div class="example-list-2">
  <mat-list-item> SOME HTML.. </mat-list-item>
</div>

以下SCSS,

[class^="example-list"] {
  mat-list-item {
    SOME SCSS..
  }
}

仅向 示例列表 2 中的 <mat-list-item> 添加样式,其中使用了 <div>

例如,如果我在 HTML 中使用 id 而不是 class和 SCSS,但我宁愿不必对代码进行大量修改。

更新

我还发现如果我禁用 Ivy 也能正常工作。

"angularCompilerOptions": {
    "enableIvy": false
 }

为什么它不能与 Ivy 一起使用?这是预期的行为吗?

我认为您遇到了 Ivy 引入的错误 https://github.com/angular/angular/issues/33111

这里的问题是添加 css classes 的顺序错误。

MatNavList 组件在元数据中有一个 host 属性 绑定:

@Component({
  selector: 'mat-nav-list',
  host: {
    'role': 'navigation',
    'class': 'mat-nav-list mat-list-base',
  },
  ...
})
export class MatNavList

https://github.com/angular/components/blob/74685883ec16782d172a4505348eef6f2003a31b/src/material/list/list.ts#L66

在 Ivy 之前,您的 class 首先被添加到元素的 class 属性中:

<mat-nav-list class="example-list-1 mat-nav-list mat-list-base"

对于早期的 Ivy 版本,它成为最后添加的 class:

<mat-nav-list class="mat-nav-list mat-list-base example-list-1"

因此,您的选择器不适用于第二种情况。但还有一个选择:

[class*="example-list"] {
  ...
}