2016-04-10 2 views
107

У меня есть родительский компонент:Как создать дочерние компоненты из css-файла родительского компонента?

<parent></parent> 

И я хочу, чтобы заполнить эту группу с дочерними компонентами:

<parent> 
    <child></child> 
    <child></child> 
    <child></child> 
</parent> 

шаблон Родитель:

<div class="parent"> 
    <!-- Children goes here --> 
    <ng-content></ng-content> 
</div> 

Детский шаблон:

<div class="child">Test</div> 

С parent и child являются двумя отдельными компонентами, их стили заперты в их собственном объеме.

В моем родительском компоненте я попытался сделать:

.parent .child { 
    // Styles for child 
} 

Но .child стили не получают применяется к child компонентов.

Я попытался с помощью styleUrls включить таблицу стилей по parent «s в child компонент для решения вопроса Область применения:

// child.component.ts 
styleUrls: [ 
    './parent.component.css', 
    './child.component.css', 
] 

Но это не помогло, а также попробовал другой путь, запрашивая в child таблицы стилей в parent но это тоже не помогло.

Итак, как вы создаете дочерние компоненты, которые включены в родительский компонент?

+1

Смотрите также http://stackoverflow.com/questions/34542143/load-external-css-style-into-angular-2-component/34963135#34963135 –

ответ

109

Update - новейший способ

Не делайте этого, если вы можете избежать этого. Как указывает Девон Санс в комментариях: эта функция, скорее всего, будет устаревшей.

Update - Новые пути

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

DEMO: https://plnkr.co/edit/RBJIszu14o4svHLQt563?p=preview

styles: [ 
    ` 
    :host { color: red; } 

    :host ::ng-deep parent { 
     color:blue; 
    } 
    :host ::ng-deep child{ 
     color:orange; 
    } 
    :host ::ng-deep child.class1 { 
     color:yellow; 
    } 
    :host ::ng-deep child.class2{ 
     color:pink; 
    } 
    ` 
], 



template: ` 
     Angular2        //red 
     <parent>        //blue 
      <child></child>      //orange 
      <child class="class1"></child>  //yellow 
      <child class="class2"></child>  //pink 
     </parent>  
    ` 


Старый путь

Вы можете использовать encapsulation mode и/или piercing CSS combinators >>>, /deep/ and ::shadow

рабочий пример: http://plnkr.co/edit/1RBDGQ?p=preview

styles: [ 
    ` 
    :host { color: red; } 
    :host >>> parent { 
     color:blue; 
    } 
    :host >>> child{ 
     color:orange; 
    } 
    :host >>> child.class1 { 
     color:yellow; 
    } 
    :host >>> child.class2{ 
     color:pink; 
    } 
    ` 
    ], 

template: ` 
    Angular2        //red 
    <parent>        //blue 
     <child></child>      //orange 
     <child class="class1"></child>  //yellow 
     <child class="class2"></child>  //pink 
    </parent>  
` 
+0

Необходимы ли компиляторы для пирсинга? Просто «.class2» в плункере все же дал те же результаты. Я что-то упускаю? –

+0

@ adam-beck Это зависит от того, как вы хотите использовать свойство 'viewencapsulation'. Он играет в нем жизненно важную роль. Вам также необходимо изучить «shadowDOM», «viewEcapsulation». – micronyks

+0

Ссылка на угловую документацию, объясняющую '>>>': https://angular.io/docs/ts/latest/guide/component-styles.html – koppor

38

После посещения страницы Github Angular2 и делает случайный поиск «стиль» Я нашел этот вопрос: Angular 2 - innerHTML styling

Который сказал, чтобы использовать то, что было добавлено в 2.0.0-beta.10, на >>> и ::shadow селекторов.

(>>>) (и эквивалент/глубоко /) и :: тень были добавлены в 2.0.0-beta.10. Они похожи на теневые компиляторы DOM CSS (которые устарели) и работают только с инкапсуляцией: ViewEncapsulation.Emulated, которая по умолчанию используется в Angular2. Вероятно, они также работают с ViewEncapsulation.None, но затем игнорируются только потому, что они не нужны. Эти комбинаторы являются лишь промежуточным решением до тех пор, пока не будут поддерживаться более сложные функции для кросс-компонентного стиля.

Так просто делать:

:host >>> .child {} 

В файл таблицы стилей parent «s решить эту проблему. Обратите внимание, что, как указано в приведенной выше цитате, это решение является промежуточным только до тех пор, пока не будет поддерживаться более продвинутый кросс-компонентный стиль.

UPDATE:

При использовании угловой CLI вы должны использовать /deep/ вместо >>> или иначе это не будет работать.

UPDATE 2:

С /deep/ и все остальные тени пирсинг селекторы теперь осуждается. Угловое падение ::ng-deep, которое следует использовать вместо этого для более широкой совместимости.

+0

Благодарим Вас за отметить относительно ':: нг-deep'. Его важно знать об этой функции. – neoswf

+0

немного больше относительно ':: ng-deep' - https://hackernoon.com/the-new-angular-ng-deep-and-the-shadow-piercing-combinators-deep-and-drop-4b088dbe459 – neoswf

+0

Похож они собираются удалить поддержку для :: ng-deep https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep – WildService

14

Если бы такой же вопрос, так что если вы используете angular2-Cli с SCSS/использование Sass '/ глубоко /' вместо '>>>', последний селектор ISN» t поддерживается (но отлично работает с css).

10

К сожалению, оказалось, что/глубокий/селектор является устаревшим (по крайней мере, в Chrome) https://www.chromestatus.com/features/6750456638341120

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

Вы можете передать объект стиля к вашему ребенку и он прикладывается через:
<div [attr.style]="styleobject">

Или если у вас есть определенный стиль, который вы можете использовать что-то вроде:
<div [style.background-color]="colorvar">

Более обсуждения, связанные с этим:

+0

Это правильный ответ на сегодня. –

9

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

Plunker: https://plnkr.co/edit/ooBRp3ROk6fbWPuToytO?p=preview

Например:

import {Component, NgModule } from '@angular/core' 
import {BrowserModule} from '@angular/platform-browser' 

@Component({ 
    selector: 'my-app', 
    template: ` 
    <div> 
     <h2>I'm the host parent</h2> 
     <child-component class="target1"></child-component><br/> 
     <child-component class="target2"></child-component><br/> 
     <child-component class="target3"></child-component><br/> 
     <child-component class="target4"></child-component><br/> 
     <child-component></child-component><br/> 
    </div> 
    `, 
    styles: [` 

    /deep/ child-component.target1 .child-box { 
     color: red !important; 
     border: 10px solid red !important; 
    } 

    /deep/ child-component.target2 .child-box { 
     color: purple !important; 
     border: 10px solid purple !important; 
    } 

    /deep/ child-component.target3 .child-box { 
     color: orange !important; 
     border: 10px solid orange !important; 
    } 

    /* this won't work because the target component is spelled incorrectly */ 
    /deep/ xxxxchild-component.target4 .child-box { 
     color: orange !important; 
     border: 10px solid orange !important; 
    } 

    /* this will affect any component that has a class name called .child-box */ 
    /deep/ .child-box { 
     color: blue !important; 
     border: 10px solid blue !important; 
    } 


    `] 
}) 
export class App { 
} 

@Component({ 
    selector: 'child-component', 
    template: ` 
    <div class="child-box"> 
     Child: This is some text in a box 
    </div> 
    `, 
    styles: [` 
    .child-box { 
     color: green;  
     border: 1px solid green; 
    } 
    `] 
}) 
export class ChildComponent { 
} 


@NgModule({ 
    imports: [ BrowserModule ], 
    declarations: [ App, ChildComponent ], 
    bootstrap: [ App ] 
}) 
export class AppModule {} 

Надеется, что это помогает!

codematrix

3

Есть несколько вариантов для достижения этой цели в Угловом:

1) Вы можете использовать глубокие CSS селекторы

:host >>> .childrens { 
    color: red; 
} 

2) Можно также изменить вид инкапсуляцию он установлен в Эмулируется по умолчанию, но может быть легко изменен на Native, который использует встроенную версию браузера Shadow DOM, в вашем случае вам просто нужно отключить его.

Например: `

import { Component, ViewEncapsulation } from '@angular/core'; 

@Component({ 
    selector: 'parent', 
    styles: [` 
    .first { 
     color:blue; 
    } 
    .second { 
     color:red; 
    } 
`], 
template: ` 
    <div> 
     <child class="first">First</child> 
     <child class="second">Second</child> 
    </div>`, 
    encapsulation: ViewEncapsulation.None, 
}) 
export class ParentComponent { 
    constructor() { 

    } 
} 
0

Я предлагаю пример, чтобы сделать его более понятным, так как angular.io/guide/component-styles состояний:

Тень прокалывания потомок комбинатор является устаревшим и поддержка удаляется из основных браузеров и инструментов. Таким образом, мы планируем отказаться от поддержки в Angular (для всех 3 of/deep /, >>> и :: ng-deep). До тех пор :: ng-deep следует предпочесть для более широкой совместимости с инструментами.

На app.component.scss при необходимости импортируйте *.scss. _colors.scss имеет некоторые общие цветовые значения:

$button_ripple_red: #A41E34; 
$button_ripple_white_text: #FFF; 

Применить правило ко всем компонентам

Все кнопки того btn-red класс будет стиль.

@import `./theme/sass/_colors`; 

// red background and white text 
:host /deep/ button.red-btn { 
    color: $button_ripple_white_text; 
    background: $button_ripple_red; 
} 

Применить правило к одному компоненту

Все кнопки, имеющей будут стиле btn-red класс по app-login компонента.

@import `./theme/sass/_colors`; 

/deep/ app-login button.red-btn { 
    color: $button_ripple_white_text; 
    background: $button_ripple_red; 
} 
2

Я нахожу много уборщика пройти @INPUT переменной, если у вас есть доступ к коду ребенка компонента:

Идея заключается в том, что родитель говорит ребенку, что его состояние внешнего вида должны быть, и ребенок решает, как отображать состояние.Это хорошая Architecture

SCSS Путь:

.active { 
    ::ng-deep md-list-item { 
    background-color: #eee; 
    } 
} 

Лучший способ: - использовать selected переменную:

<md-list> 
    <a 
      *ngFor="let convo of conversations" 
      routerLink="/conversations/{{convo.id}}/messages" 
      #rla="routerLinkActive" 
      routerLinkActive="active"> 
     <app-conversation 
       [selected]="rla.isActive" 
       [convo]="convo"></app-conversation> 
    </a> 
</md-list> 
+2

Это не будет работать с сторонними компонентами, которые не имеют такого свойства. :( –

0

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

<parent> 
    <child [foo]="bar"></child> 
</parent> 

Угловая унижает все способы воздействия на детские стили родителей.

https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep

+0

Это сломает почти все библиотеки, поэтому я сомневаюсь, что они полностью удалят поддержку. – Chrillewoodz

+0

Ну, они прямо сказали в своих документах, что они делают это в конечном итоге, и я думаю, что они это сделают. Я согласен, хотя, а не Это происходит в ближайшее время. – WildService

+0

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

Смежные вопросы