Инкапсуляция стилевого представления углового компонента не работает, когда файл scss компонента импортируется в файл scss стилей

Представьте, что в файле my.component.scss компонента Angular есть смесь SCSS.

Сейчас я импортирую этот файл в глобальный style.scss приложения Angular, потому что я хотел бы передать некоторые данные в этот миксин.

Например: my-component.scss.

<pre>
 @mixin my-component-theming($theme) {
     // Extract whichever individual palettes you need from the theme.
     $warn-palette: map-get($theme, warn);

     $warn: mat-color($primary-palette);

     .error-message {
        color: $warn !important;
      }
   }
</pre>

мой-component.ts

<pre>

 @Component({
   selector: 'my-component',
   templateUrl: './my-component.html',
   styleUrls: ['./my-component.scss']
})

</pre>

Стили углового приложения. (Это импортируется в Angular.json)

<pre>
    @import '~@angular/material/theming';
    @import 'my-component.scss';

    // just imagine that $app-theme is already defined here. 
    // Not including unnecessary code to keep example simple.

    @include my-component-theming($app-theme)
</pre>

Он выполняет компиляцию и работу приложения, как и ожидалось, но мой класс css "error-message" доступен всему приложению.

Angular должен был инкапсулировать класс css "error-message", и его видимость должна быть ограничена только my-component. Как я могу сохранить инкапсуляцию в этом случае?

PS: я просто пытаюсь сделать это: https://material.angular.io/guide/theming, но эта проблема, как представляется, более общая.

Заранее спасибо. Дайте мне знать, если необходимы дальнейшие разъяснения или код.

1 ответ

Тематика и стиль инкапсуляции - это две разные вещи. Angular будет только инкапсулировать код стиля в таблицу стилей вашего компонента; он не инкапсулирует какие-либо миксины, определенные там, потому что миксины должны быть вызваны для применения. И где вы определяете, что миксин не имеет ничего общего с тем, где этот миксин применяется - это ваше дело. Ваш класс ошибок доступен всему приложению, потому что вы назвали его в своей основной таблице стилей.

В конечном счете, вы не можете использовать их и инкапсулировать, потому что способ, которым они работают, распространяется на все приложения. Поэтому, чтобы обойти это, используйте селектор вашего компонента, чтобы ограничить область видимости вашего миксина:

@mixin my-component-theming($theme) {
  // Extract whichever individual palettes you need from the theme.
  $warn-palette: map-get($theme, warn);

  $warn: mat-color($primary-palette);

  my-component.error-message {
    color: $warn !important;
  }
}

Это по-прежнему определяет стиль приложения в целом, но это повлияет только на ваш компонент.

Кроме того, вы не должны включать миксины тем ваших компонентов в таблицы стилей компонентов. Они должны быть в их собственном файле тем, чтобы при импорте миксина для тем вы не импортировали - в основную таблицу стилей приложения - какие-либо не связанные с темами стили для компонента.

При этом вы можете попытаться инкапсулировать темы вашего компонента. Вам нужно будет получить доступ к своей глобальной теме в таблице стилей вашего компонента, и вам также может понадобиться импортировать утилиты тематического углового материала в вашу таблицу стилей компонента. Я не уверен, будет ли это работать, и я думаю, что это может добавить много дублирования стилей в вашем приложении, если вы сделаете это для большого количества компонентов.

Другие вопросы по тегам