Инкапсуляция стилевого представления углового компонента не работает, когда файл 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;
}
}
Это по-прежнему определяет стиль приложения в целом, но это повлияет только на ваш компонент.
Кроме того, вы не должны включать миксины тем ваших компонентов в таблицы стилей компонентов. Они должны быть в их собственном файле тем, чтобы при импорте миксина для тем вы не импортировали - в основную таблицу стилей приложения - какие-либо не связанные с темами стили для компонента.
При этом вы можете попытаться инкапсулировать темы вашего компонента. Вам нужно будет получить доступ к своей глобальной теме в таблице стилей вашего компонента, и вам также может понадобиться импортировать утилиты тематического углового материала в вашу таблицу стилей компонента. Я не уверен, будет ли это работать, и я думаю, что это может добавить много дублирования стилей в вашем приложении, если вы сделаете это для большого количества компонентов.