Jestem nowy w Angular 4, więc czy ktoś mógłby wyjaśnić, jak i gdzie używać ::ng-deep
Angular 4?
Właściwie chcę nadpisać niektóre właściwości CSS komponentów potomnych z komponentów nadrzędnych. Co więcej, czy jest obsługiwany w IE11?
Jestem nowy w Angular 4, więc czy ktoś mógłby wyjaśnić, jak i gdzie używać ::ng-deep
Angular 4?
Właściwie chcę nadpisać niektóre właściwości CSS komponentów potomnych z komponentów nadrzędnych. Co więcej, czy jest obsługiwany w IE11?
Odpowiedzi:
Zwykle /deep/ “shadow-piercing”
można użyć kombinatora, aby wymusić obniżenie stylu child components
. Ten selektor miał alias >>>, a teraz ma inny o nazwie :: ng-deep.
ponieważ /deep/ combinator
został uznany za przestarzały, zaleca się użycie::ng-deep
Na przykład:
<div class="overview tab-pane" id="overview" role="tabpanel" [innerHTML]="project?.getContent( 'DETAILS')"></div>
i css
.overview {
::ng-deep {
p {
&:last-child {
margin-bottom: 0;
}
}
}
}
zostanie zastosowany do komponentów potomnych
::ng-deep
, >>>
A /deep/
wyłączenie enkapsulacji widok konkretnych reguł CSS, innymi słowy, daje dostęp do elementów DOM, które nie znajdują się w kodzie HTML składnika. Na przykład, jeśli używasz Angular Material (lub dowolnej innej biblioteki takiej jak ta), niektóre wygenerowane elementy znajdują się poza obszarem twojego komponentu (na przykład okno dialogowe ) i nie możesz uzyskać dostępu do tych elementów bezpośrednio lub za pomocą zwykłego CSS sposób. Jeśli chcesz zmienić style tych elementów, możesz użyć jednej z tych trzech rzeczy, na przykład:
::ng-deep .mat-dialog {
/* styles here */
}
Na razie zespół Angular zaleca wykonywanie „głębokich” manipulacji tylko przy użyciu hermetyzacji widoku EMULOWANEGO .
„głębokie” manipulacje również są przestarzałe , ALE na razie nadal działa, ponieważ Angular obsługuje przetwarzanie wstępne (nie spiesz się, aby odmówić ::ng-deep
dzisiaj, zapoznaj się z praktykami wycofywania najpierw ).
W każdym razie, zanim pójdziesz w ten sposób, polecam przyjrzeć się wyłączaniu podejścia hermetyzacji widoku (co też nie jest idealne, pozwala stylom przeniknąć do innych komponentów), ale w niektórych przypadkach jest to lepszy sposób. Jeśli zdecydowałeś się wyłączyć hermetyzację widoku, zdecydowanie zaleca się użycie określonych klas, aby uniknąć przecinania się reguł CSS, a na koniec uniknąć bałaganu w arkuszach stylów. Naprawdę łatwo jest wyłączyć bezpośrednio w .ts
pliku komponentu :
@Component({
selector: '',
template: '',
styles: [''],
encapsulation: ViewEncapsulation.None // Use to disable CSS Encapsulation for this component
})
Więcej informacji na temat hermetyzacji widoku można znaleźć w tym artykule.
ViewEncapsulation.None
! Spowoduje wiele szkód, umożliwiając przenikanie tych stylów do innych elementów.
Chciałbym podkreślić znaczenie ograniczenia ::ng-deep
tylko dzieci składnika poprzez wymaganie, aby rodzic był hermetyzowaną klasą css.
Aby to zadziałało, ważne jest, aby użyć ::ng-deep
po rodzicu, a nie wcześniej, w przeciwnym razie będzie to miało zastosowanie do wszystkich klas o tej samej nazwie w momencie ładowania składnika.
CSS komponentu:
.my-component ::ng-deep .mat-checkbox-layout {
background-color: aqua;
}
Szablon komponentu:
<h1 class="my-component">
<mat-checkbox ....></mat-checkbox>
</h1>
Wynikowy (wygenerowany przez Angular) CSS:
.my-component[_ngcontent-c1] .mat-checkbox-layout {
background-color: aqua;
}
EDYTOWAĆ:
Możesz osiągnąć to samo zachowanie, używając :host
słowa kluczowego zamiast tworzenia nowej klasy CSS.
:host ::ng-deep .mat-checkbox-layout
my-component ::ng-deep...
uratowała mi dzień. Spędziłem cały dzień próbując zastosować styl dla mojego komponentu za pomocą ng-deep i nadpisałem wszystkie moje komponenty z całej mojej aplikacji.
:host
słowem kluczowym - dodano notatkę do odpowiedzi dla jasności.
Upewnij się, że nie przegapisz wyjaśnienia, :host-context
które znajduje się bezpośrednio powyżej ::ng-deep
w przewodniku kątowym: https://angular.io/guide/component-styles . Zastrzeżenie: przegapiłem to do tej pory i żałuję, że nie widziałem tego wcześniej.
::ng-deep
jest często konieczne, gdy nie napisałeś komponentu i nie masz dostępu do jego źródła, ale :host-context
może być bardzo przydatną opcją, gdy to zrobisz.
Na przykład mam czarny <h1>
nagłówek wewnątrz zaprojektowanego przeze mnie komponentu i chcę mieć możliwość zmiany go na biały, gdy jest wyświetlany na ciemnym tle tematycznym.
Jeśli nie miałem dostępu do źródła, być może będę musiał to zrobić w css dla rodzica:
.theme-dark widget-box ::ng-deep h1 { color: white; }
Ale zamiast tego :host-context
możesz to zrobić wewnątrz komponentu.
h1
{
color: black; // default color
:host-context(.theme-dark) &
{
color: white; // color for dark-theme
}
// OR set an attribute 'outside' with [attr.theme]="'dark'"
:host-context([theme='dark']) &
{
color: white; // color for dark-theme
}
}
Spowoduje to wyszukanie dowolnego miejsca w łańcuchu komponentów .theme-dark
i zastosowanie CSS do h1, jeśli zostanie znaleziony. To dobra alternatywa dla zbytniego polegania::ng-deep
która choć często jest konieczna, jest rodzaju anty-wzorca.
W tym przypadku &
jest zastępowany przezh1
(tak działa sass / scss), więc możesz zdefiniować swój „normalny” i tematyczny / alternatywny css tuż obok siebie, co jest bardzo przydatne.
Uważaj, aby uzyskać prawidłową liczbę plików :
. Bo ::ng-deep
jest dwóch i :host-context
tylko jeden.
:host(.theme-dark)
jeśli nie chcesz dziedziczyć theme-dark
z żadnych komponentów nadrzędnych. Będzie to całkowicie zależało od projektu CSS Twojej witryny. Również atrybuty mogą być bardzo przydatne i można je łączyć w wyrafinowany sposób w samym CSS:host([theme='dark']:not([dayofweek='tuesday'))
.theme-light
klasę, to z kolei jest zagnieżdżona w kontenerze, w .theme-dark
którym nadal pobierze theme-dark
i zastosuje css. Ale jest to świetne rozwiązanie dla klas typu „modernizr” lub jeśli masz motyw ustawiony globalnie i tylko raz.
Tylko aktualizacja:
Należy użyć ::ng-deep
zamiast tego, /deep/
który wydaje się być przestarzały.
Według dokumentacji:
Przerywający cień kombinator potomków jest przestarzały, a jego obsługa jest usuwana z głównych przeglądarek i narzędzi. W związku z tym planujemy porzucić obsługę Angulara (dla wszystkich 3 z / deep /, >>> i :: ng-deep). Do tego czasu należy preferować :: ng-deep ze względu na szerszą kompatybilność z narzędziami.
Znajdziesz go tutaj
Używaj :: ng-deep z rozwagą. Używałem go w całej mojej aplikacji, aby ustawić różne kolory paska narzędzi Material Design na różne kolory w całej aplikacji, tylko po to, aby stwierdzić, że podczas testowania aplikacji kolory pasków narzędzi nakładają się na siebie. Przekonaj się, że to dlatego, że te style stają się globalne, zobacz ten artykuł Oto działające rozwiązanie kodu, które nie przenika do innych komponentów.
<mat-toolbar #subbar>
...
</mat-toolbar>
export class BypartSubBarComponent implements AfterViewInit {
@ViewChild('subbar', { static: false }) subbar: MatToolbar;
constructor(
private renderer: Renderer2) { }
ngAfterViewInit() {
this.renderer.setStyle(
this.subbar._elementRef.nativeElement, 'backgroundColor', 'red');
}
}
/deep/
i::ng-deep
są przestarzałe, sugeruję zapoznanie się z tą odpowiedzią stackoverflow.com/a/49308475/2275011 i komentarzami, aby uzyskać więcej szczegółów i rozwiązań.