Лучший способ передать стиль компоненту

Итак, у меня есть этот компонент с именем 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');

Затем ваш компонент может проверить свое значение одним из нескольких способов стилизации себя:

  1. Изменить сам HTML, показывая или скрывая дочерние элементы

    <h1 *ngIf="headerSize == 'large'">{{ title }}</h1>
    <h2 *ngIf="headerSize == 'small'">{{ title }}</h2>
    
  2. Установите динамический класс внутри компонента и стилизуйте его:

    <div [ngClass]="'header-' + headerSize">
    
    .header-small { h1 { font-size: 20px; } }
    .header-large { h1 { font-size: 30px; } }
    
  3. Установите пользовательский класс динамически на уровне класса. Это то же самое, что и # 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);
}

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