Ich habe eine übergeordnete Komponente:
<parent></parent>
Und ich möchte diese Gruppe mit untergeordneten Komponenten füllen:
<parent>
<child></child>
<child></child>
<child></child>
</parent>
Übergeordnete Vorlage:
<div class="parent">
<!-- Children goes here -->
<ng-content></ng-content>
</div>
Untergeordnete Vorlage:
<div class="child">Test</div>
Schon seit parent
und child
zwei separate Komponenten sind, sind ihre Stile an ihren eigenen Bereich gebunden.
In meiner übergeordneten Komponente habe ich versucht:
.parent .child {
// Styles for child
}
Aber die .child
Stile werden jedoch nicht auf die child
Komponenten angewendet .
Ich habe versucht styleUrls
, das parent
Stylesheet des Stylesheets in die child
Komponente aufzunehmen, um das Scope-Problem zu lösen:
// child.component.ts
styleUrls: [
'./parent.component.css',
'./child.component.css',
]
Aber das hat nicht geholfen, auch in die andere Richtung versucht, indem das child
Stylesheet abgerufen wurde, parent
aber das hat auch nicht geholfen.
Wie formatieren Sie untergeordnete Komponenten, die in einer übergeordneten Komponente enthalten sind?
quelle
Antworten:
Update - Neuester Weg
Tu es nicht, wenn du es vermeiden kannst. Wie Devon Sans in den Kommentaren betont: Diese Funktion wird höchstwahrscheinlich veraltet sein.
Update - Neuerer Weg
Ab Angular 4.3.0 waren alle Piercing-CSS-Kombinatoren veraltet. Das Angular-Team hat einen neuen Kombinator eingeführt
::ng-deep
(er befindet sich noch auf experimentellem Niveau und nicht auf dem vollständigen und endgültigen Weg), wie unten gezeigt.DEMO: https://plnkr.co/edit/RBJIszu14o4svHLQt563?p=preview
Alter Weg
Sie können
encapsulation mode
und / oder verwendenpiercing CSS combinators >>>, /deep/ and ::shadow
Arbeitsbeispiel: http://plnkr.co/edit/1RBDGQ?p=preview
quelle
::ng-deep
ist jetzt veraltet , ich empfehle nicht, es in zukünftigen Anwendungen zu verwendenUPDATE 3:
::ng-deep
ist ebenfalls veraltet, was bedeutet, dass Sie dies überhaupt nicht mehr tun sollten. Es ist unklar, wie sich dies auf Dinge auswirkt, bei denen Sie Stile in untergeordneten Komponenten von einer übergeordneten Komponente überschreiben müssen. Für mich ist es seltsam, wenn dies vollständig entfernt wird, denn wie würde sich dies auf Dinge als Bibliotheken auswirken, bei denen Sie Stile in einer Bibliothekskomponente überschreiben müssen?Kommentar, wenn Sie einen Einblick in diese haben.
UPDATE 2:
Da
/deep/
und alle anderen Schattenpiercing-Selektoren sind jetzt veraltet. Angular Drop::ng-deep
, der stattdessen für eine breitere Kompatibilität verwendet werden sollte.AKTUALISIEREN:
Wenn Sie Angular-CLI verwenden, müssen Sie
/deep/
anstelle von verwenden,>>>
sonst funktioniert es nicht.ORIGINAL:
Nachdem ich auf Angular2s Github-Seite gegangen war und eine zufällige Suche nach "Stil" durchgeführt hatte, fand ich folgende Frage: Angular 2 - innerHTML- Stil
Welches sagte, um etwas zu verwenden, das hinzugefügt wurde
2.0.0-beta.10
, die>>>
und::shadow
Selektoren.Also einfach machen:
In
parent
der Stylesheet-Datei wurde das Problem behoben. Bitte beachten Sie, dass diese Lösung, wie im obigen Zitat angegeben, nur zwischenzeitlich erfolgt, bis ein erweitertes komponentenübergreifendes Styling unterstützt wird.quelle
Sie sollten NICHT verwenden
::ng-deep
, es ist veraltet. In Angular können Sie den Stil der Kinderkomponente vom übergeordneten Element aus ordnungsgemäß ändernencapsulation
(lesen Sie die folgende Warnung, um die Auswirkungen zu verstehen):Und dann können Sie das CSS-Formular Ihrer Komponente ändern, ohne dass :: ng-deep erforderlich ist
WARNUNG: Wenn Sie dies tun, werden alle CSS-Regeln, die Sie für diese Komponente schreiben, global.
Um den Umfang Ihres CSS nur auf diese Komponente zu beschränken, fügen Sie dem obersten Tag Ihrer Komponente eine CSS-Klasse hinzu und fügen Sie Ihr CSS "in" dieses Tag ein:
Scss-Datei:
quelle
::ng-deep
. Im Allgemeinen haben Komponenten ohnehin einen eigenen Selektor (<my-component>, <div my-component>
usw.), sodass nicht einmal ein Wrapper-Element mit einer speziellen Klasse erforderlich ist.Leider scheint der / deep / Selektor (zumindest in Chrome) veraltet zu sein. Https://www.chromestatus.com/features/6750456638341120
Kurz gesagt, es scheint (derzeit) keine andere langfristige Lösung zu geben, als Ihre untergeordnete Komponente dazu zu bringen, Dinge dynamisch zu gestalten.
Sie können Ihrem Kind ein Stilobjekt übergeben und es anwenden lassen über:
<div [attr.style]="styleobject">
Oder wenn Sie einen bestimmten Stil haben, können Sie Folgendes verwenden:
<div [style.background-color]="colorvar">
Weitere Diskussionen dazu: https://github.com/angular/angular/issues/6511
quelle
Hatte das gleiche Problem. Wenn Sie also angle2-cli mit scss / sass verwenden und '/ deep /' anstelle von '>>>' verwenden, wird der letzte Selektor noch nicht unterstützt (funktioniert aber hervorragend mit CSS).
quelle
Wenn Sie gezielter auf die eigentliche untergeordnete Komponente ausgerichtet sein möchten, sollten Sie die folgenden Schritte ausführen. Auf diese Weise sind andere untergeordnete Komponenten, die denselben Klassennamen haben, nicht betroffen.
Plunker: https://plnkr.co/edit/ooBRp3ROk6fbWPuToytO?p=preview
Beispielsweise:
Hoffe das hilft!
Codematrix
quelle
Eigentlich gibt es noch eine Option. Welches ist ziemlich sicher. Sie können ViewEncapsulation.None verwenden, ABER alle Ihre Komponentenstile in das Tag (auch bekannt als Selector) einfügen. Aber trotzdem bevorzugen Sie immer einen globalen Stil plus gekapselte Stile.
Hier ist modifiziertes Denis Rybalka Beispiel:
quelle
In Angular gibt es einige Optionen, um dies zu erreichen:
1) Sie können Deep-CSS-Selektoren verwenden
2) Sie können auch die Ansichtskapselung ändern, die standardmäßig auf Emuliert eingestellt ist. Sie kann jedoch problemlos in Native geändert werden, wobei die native Browser-Implementierung von Shadow DOM verwendet wird. In Ihrem Fall müssen Sie sie nur deaktivieren
Zum Beispiel: `
quelle
Sie sollten keine CSS-Regeln für untergeordnete Komponentenelemente in eine übergeordnete Komponente schreiben, da eine Angular-Komponente eine in sich geschlossene Entität ist, die explizit deklarieren sollte, was für die Außenwelt verfügbar ist. Wenn sich das untergeordnete Layout in Zukunft ändert, können Ihre Stile für die untergeordneten Komponentenelemente, die über die SCSS-Dateien anderer Komponenten verteilt sind, leicht beschädigt werden, wodurch Ihr Stil sehr fragil wird. Das ist, was
ViewEncapsulation
ist CSS gedacht. Andernfalls wäre es dasselbe, wenn Sie privaten Feldern einer Klasse aus einer anderen Klasse in der objektorientierten Programmierung Werte zuweisen könnten.Daher sollten Sie eine Reihe von Klassen definieren, die Sie auf das untergeordnete Hostelement anwenden können, und implementieren, wie das untergeordnete Element darauf reagiert.
Technisch könnte dies wie folgt erfolgen:
Mit anderen Worten, Sie verwenden den
:host
Pseudo-Selektor, der von Angular + CSS-Klassen bereitgestellt wird, um mögliche untergeordnete Stile in der untergeordneten Komponente selbst zu definieren. Sie haben dann die Möglichkeit, diese Stile von außen auszulösen, indem Sie vordefinierte Klassen auf das<child>
Hostelement anwenden .quelle
parent.component.scss
Bezug auf das Styling der untergeordneten Komponente geben. Dies ist der einzige Zweck dieses Ansatzes. Warum brauchen Sieparent.component.scss
?ViewEncapsulation
nur, weil sein Standardwert zur OP-Frage führt. Sie müssen keinen anderenViewEncapsulation
Code zuweisen, damit der obige Code funktioniert.Ich finde es viel sauberer, eine @ INPUT-Variable zu übergeben, wenn Sie Zugriff auf den untergeordneten Komponentencode haben:
Die Idee ist, dass der Elternteil dem Kind sagt, wie es aussehen soll, und das Kind entscheidet, wie der Zustand angezeigt werden soll. Es ist eine schöne Architektur
SCSS-Weg:
Besserer Weg: -
selected
Variable verwenden:quelle
Ab heute (Angular 9) verwendet Angular ein Shadow-DOM , um die Komponenten als benutzerdefinierte HTML-Elemente anzuzeigen . Eine elegante Möglichkeit, diese benutzerdefinierten Elemente zu formatieren, ist möglicherweise die Verwendung benutzerdefinierter CSS-Variablen . Hier ist ein allgemeines Beispiel:
Wie aus dem obigen Code hervorgeht, erstellen wir ein benutzerdefiniertes Element, wie es Angular für jede Komponente tun würde, und überschreiben dann die für die Hintergrundfarbe verantwortliche Variable innerhalb der Schattenwurzel des benutzerdefinierten Elements aus dem globalen Bereich .
In einer Angular-App könnte dies etwa so aussehen:
parent.component.scss
child-element.component.scss
quelle
Die schnelle Antwort lautet: Sie sollten dies überhaupt nicht tun. Es unterbricht die Kapselung von Komponenten und untergräbt den Nutzen von in sich geschlossenen Komponenten. Wenn Sie ein Prop-Flag an die untergeordnete Komponente übergeben möchten, kann diese selbst entscheiden, wie sie anders rendern oder bei Bedarf anderes CSS anwenden soll.
Angular lehnt alle Möglichkeiten ab, die Kinderstile der Eltern zu beeinflussen.
https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep
quelle
Ich hatte auch dieses Problem und wollte keine veraltete Lösung verwenden, also endete ich mit:
in parrent
untergeordnete Komponente
im Kind in HTML div
und im Code
funktioniert wie erwartet und sollte nicht veraltet sein;)
quelle
Als das Internet aktualisiert wurde, bin ich auf eine Lösung gestoßen.
Zuerst einige Vorbehalte.
Markieren Sie zunächst die Kapselung Ihrer untergeordneten Komponente als Schatten, damit sie im tatsächlichen Schattendom gerendert wird. Fügen Sie zweitens das Teilattribut zu dem Element hinzu, das das übergeordnete Element formatieren soll. Im Komponenten-Stylesheet Ihrer Eltern können Sie mit der Methode :: part () darauf zugreifen
quelle
Ich schlage ein Beispiel vor, um es klarer zu machen, da angular.io/guide/component-styles Folgendes angibt:
Auf
app.component.scss
, importieren Sie Ihre ,*.scss
wenn nötig._colors.scss
hat einige gemeinsame Farbwerte:Wenden Sie eine Regel auf alle Komponenten an
Alle Schaltflächen mit
btn-red
Klasse werden gestylt.Wenden Sie eine Regel auf eine einzelne Komponente an
Alle Schaltflächen mit
btn-red
Klasse fürapp-login
Komponente werden so gestaltet.quelle
Ich habe es außerhalb von Angular gelöst. Ich habe ein freigegebenes scss definiert, das ich in meine Kinder importiere.
shared.scss
child.scss
Mein vorgeschlagener Ansatz ist ein Weg, um das Problem zu lösen, nach dem das OP gefragt hat. Wie bereits mehrfach erwähnt, wird :: ng-deep ,: ng-host abgeschrieben, und das Deaktivieren der Kapselung ist meiner Ansicht nach ein zu großer Codeverlust.
quelle