Лучший способ передать стиль компоненту
Итак, у меня есть этот компонент с именем InputEdit
(в основном, это Label
который можно редактировать, когда вы щелкаете по нему... достаточно просто), и у этого компонента есть собственный затененный стиль DOM CSS. Но, конечно, каждый хостинг-компонент захочет установить свой размер и цвет шрифта для компонента ввода...
Так что будет лучшим способом? Можете ли вы просто передать класс стилей и применить весь CSS к компоненту? Или было бы лучше передать каждое значение вручную, как в:
<InputEdit [color]="'red'"/>
Это может показаться трудоемким, но опять же, поскольку мы используем теневую или эмулированную модель DOM, мы не можем просто контролировать CSS извне.
Я также знаю, что вы можете соединить тень и нацелить прямые элементы с помощью:
/* styles.css */
UserInfo /deep/ InputEdit label {
color: red;
font-size: 1.1em;
}
Что в основном позволит вам войти в пользовательский компонент с именем UserInfo/deep (любой уровень)/пользовательский компонент InputEdit и целевую метку с красным цветом...
Но опять же, мне интересно, что является лучшим подходом специально для ng2, как, например, передача конфигурации класса в директиву?
Ответы
Ответ 1
Я бы просто использовал свойство ввода styles
на InputEdit и передал объект с нужными стилями:
<InputEdit [styles]="stylesObj"> // in host component template
stylesObj = {font-size: '1.1em', color: 'red'}; // in host component class
<input [ngStyle]="stylesObj" ...> // in InputEdit component template
Если у вас есть несколько элементов DOM, которые вы хотите создать, перейдите к более сложному объекту:
<InputEdit [styles]="stylesObj">
stylesObj = {
input: {font-size: '1.1em', color: 'red'}
label: { ... }
};
<label [ngStyle]="styles.label" ...>
<input [ngStyle]="styles.input" ...>
Ответ 2
Обновить
::slotted
теперь поддерживается всеми новыми браузерами и может использоваться с 'ViewEncapsulation.ShadowDom
https://developer.mozilla.org/en-US/docs/Web/CSS/::slotted
оригинал
/deep/
, ::shadow
и >>>
устарели. ::ng-deep
- лучший вариант, пока все браузеры не будут должным образом поддерживать инкапсуляцию стилей, и ViewEncapsulation.Emulated
можно удалить.
Устаревание только для собственной реализации в Chrome (другие браузеры никогда не реализовывали ее), но Angular имеет собственную эмуляцию этих CSS-комбинаторов в ViewEncapsulation.Emulated
(по умолчанию)
/deep/
, ::shadow
и >>>
::ng-deep
могут поэтому отлично использоваться в Angular2.
Для более чем простых классов или настроек свойств стиля используйте ngStyle
Angular 2.0 и стиль ng
Ответ 3
Ответ Mark Rajcok хорош для группы стилей, но если вы позволите изменить размер шрифта и цвет, вы можете захотеть чтобы использовать более прямой подход, как вы начали (в этом примере также можно использовать только пиксели вместо более гибкой строки для демонстрационных целей):
ДЛЯ ИНДИВИДУАЛЬНЫХ СТИЛЬНЫХ СВОЙСТВ:
Компонент:
<InputEdit [color]="'red'" [fontSize]="16">
component.ts:
Input() color: string = 'black';
Input() fontSize: number = 18;
component.template:
<input type="text" [style.color]="color" [style.fontSize.px]="fontSize">
ЕСЛИ ПОЗВОЛЯЕТ ГРУППУ СТИЛЕЙ:
Компонент:
<InputEdit [styles]="{backgroundColor: 'blue', 'font-size': '16px'}">
ПРИМЕЧАНИЕ.
Убедитесь, что свойства CSS находятся в camelCased или в строке, если есть несколько слов.
component.ts:
@Input() styles: any = {};
component.template:
<input type="text" [ngStyle]="styles">
Ответ 4
Если вы хотите оставить это для компонента для определения фактического CSS, вы можете попробовать одно из следующих:
Добавьте свойство в свой компонент для каждого "логического" параметра стиля, например headerSize
.
@Input('headerSize') headerSize: ('small' | 'large');
Затем ваш компонент может проверить свое значение одним из нескольких способов стилизации себя:
-
Изменить сам HTML, показывая или скрывая дочерние элементы
<h1 *ngIf="headerSize == 'large'">{{ title }}</h1>
<h2 *ngIf="headerSize == 'small'">{{ title }}</h2>
-
Установите динамический класс внутри компонента и стилизуйте его:
<div [ngClass]="'header-' + headerSize">
.header-small { h1 { font-size: 20px; } }
.header-large { h1 { font-size: 30px; } }
-
Установите пользовательский класс динамически на уровне класса. Это то же самое, что и # 2, и не требует элемента-оболочки. Однако это меньше, чем тривиальное на самом деле включить и отключить эти классы.
@HostBinding('class.header-small') _header_small;
@HostBinding('class.header-large') _header_large;
Также обратите внимание, что если вы используете ng-content
, то применяемыми стилями являются стили, определенные в содержащем компоненте, а не компонент, который фактически выполняет замену содержимого.
Ответ 5
Другой вариант - использовать переменные CSS. В этом случае, чтобы стилизовать цвет и размер шрифта метки дочернего компонента, вы можете установить две переменные в родительском компоненте CSS и использовать их в дочернем CSS.
userInfo.component.css
InputEdit {
--label-color: red;
--label-font-size: 1.1em;
}
inputEdit.component.css
label {
color: var(--label-color, #000);
font-size: var(--label-font-size, 1em);
}
Конечно, это означает, что вам нужно определить каждое свойство, которое вы хотите стилизовать, но если вам нужно только установить несколько стилей для дочернего элемента, это работает нормально.