Угловой компонент для применения родительских указанных стилей

#html #css #angular #web-component

#HTML #css #angular #веб-компонент

Вопрос:

Я знаю, как использовать ::ng-deep для применения стилей к внутренним частям конкретного компонента, но я ищу более правильное решение, которое не требует, чтобы родитель знал о компонентах, и, в частности, для установки размеров компонента (ширина и высота).

Вот полный сценарий:

 @Component({
  selector: 'app-root',
  template: '<h1>Hello World!<h1><app-green-box></app-green-box>',
  styles: [ 'app-green-box { width: 50%; }' ],
})
export class AppComponent {
}

@Component({
  selector: 'app-green-box',
  template: '<div class="green-box">Bye</div>',
  styles: [ '.green-box { border: solid black 1px; background: green; }' ],
})
export class GreenBoxComponent {
}
  

Как вы можете видеть, AppComponent хотелось бы, чтобы зеленый прямоугольник был шириной 50%. GreenBoxComponent у него нет способа узнать это (другой родитель может захотеть, чтобы это было на 70% или на 10%).

К сожалению, приведенный выше код не работает (я не совсем уверен, почему — пользовательский элемент на самом деле не занимает места, поскольку сам по себе не имеет визуального представления, и поэтому он не может быть ограничивающим прямоугольником для содержимого?).

Использование ::ng-deep требует, чтобы родительский компонент знал, что GreenBoxComponent использует <div> для своей внутренней реализации box, но есть ли способ заставить компонент просто «копировать» стили с хоста в любую внутреннюю часть, к которой ему нужно их применить?

Ответ №1:

На самом деле, после попытки объяснить себе причину, по которой пользовательский элемент не является ограничивающей рамкой (в вопросе), я выяснил проблему: по умолчанию display для пользовательского элемента установлено значение inline , поэтому он не подчиняется ограничениям родительского размера.

Решение заключается в том, чтобы GreenBoxComponent понять, что он представляет собой поле, а не встроенный элемент, и что родители хотели бы рассматривать его как поле, поэтому он должен заставить свой хост-элемент иметь display: block , вот так:

 @Component({
  selector: 'app-green-box',
  template: '<div class="green-box">Bye</div>',
  styles: [ 
    ':host { display: block; }',
    '.green-box { border: solid black 1px; background: green; }',
  ],
})
export class GreenBoxComponent {
}
  

Комментарии:

1. Мощь отладки rubber duck — приятная 🤓.