Angenommen, ich habe eine Komponente:
@Component({
selector: 'MyContainer',
template: `
<div class="container">
<!-- some html skipped -->
<ng-content></ng-content>
<span *ngIf="????">Display this if ng-content is empty!</span>
<!-- some html skipped -->
</div>`
})
export class MyContainer {
}
Jetzt möchte ich einige Standardinhalte anzeigen, wenn <ng-content>
diese Komponente leer ist. Gibt es eine einfache Möglichkeit, dies zu tun, ohne direkt auf das DOM zuzugreifen?
javascript
angular
Slawomir Dadas
quelle
quelle
Antworten:
Schließen Sie
ng-content
ein HTML-Element wie ein eindiv
, um einen lokalen Verweis darauf zu erhalten, und binden Sie denngIf
Ausdruck dann anref.children.length == 0
:quelle
ref.children.length
. childNodes enthälttext
Knoten, wenn Sie Ihren HTML- Code mit Leerzeichen oder neuen Zeilen formatieren, untergeordnete Knoten jedoch weiterhin leer sind.ref.childNodes.length == 0
anstelle von verwendet haberef.children.length == 0
. Es würde einem Haufen helfen, wenn Sie die Antwort so bearbeiten könnten, dass sie konsistent ist. Einfacher Fehler, dich nicht zu verprügeln. :)ref.nativeElement.childNodes.length
. Könnte diese Antwort bitte bearbeitet werden?In @pixelbits fehlen einige Antworten. Wir müssen nicht nur die
children
Eigenschaft überprüfen , da Zeilenumbrüche oder Leerzeichen in der übergeordneten Vorlage einchildren
Element mit leerem Text \ Zeilenumbruch verursachen. Besser zu überprüfen.innerHTML
und.trim()
es.Arbeitsbeispiel:
quelle
EDIT 17.03.2020
Reines CSS (2 Lösungen)
Stellt Standardinhalte bereit, wenn nichts in ng-content projiziert wird.
Mögliche Selektoren:
:only-child
Wähler. Siehe diesen Beitrag hier :: only-child SelectorDieser erfordert weniger Code / Markup. Unterstützung seit IE 9: Kann ich verwenden: nur Kind
:empty
Wähler. Lesen Sie einfach weiter.Unterstützung von IE 9 und teilweise seit IE 7/8: https://caniuse.com/#feat=css-sel3
HTML
CSS
Falls es nicht funktioniert
Beachten Sie, dass mindestens ein Leerzeichen nicht leer ist. Angular entfernt Leerzeichen, aber nur für den Fall, dass dies nicht der Fall ist:
oder
quelle
empty
CSS-Pseudoklasse hatten<loader [data]="allDataWeNeed"> <desired-component *loadingRender><desired-component> <other-default-component *renderWhenEmptyResult></other-default-component> </loader>
In der Ladekomponente können Sie währenddessen die wahrgenommene Leistungsbelastung anzeigen Die Daten werden geladen. Sie können es auf verschiedene Arten schreiben / lösen. Dies ist eine Demonstration, wie Sie es lösen können.Wenn Sie den Inhalt einfügen, fügen Sie eine Referenzvariable hinzu:
und in Ihrer Komponentenklasse erhalten Sie mit @ContentChild () einen Verweis auf den injizierten Inhalt
In Ihrer Komponentenvorlage können Sie also überprüfen, ob die Inhaltsvariable einen Wert hat
quelle
<MyContainer></MyContainer>
. Ihre Lösung erwartet, dass Benutzer unter MyContainer ein Unterelement erstellen :<MyContainer><div #content></div></MyContainer>
. Obwohl dies eine Möglichkeit ist, würde ich nicht sagen, dass dies überlegen ist.Injizieren
elementRef: ElementRef
und prüfen, obelementRef.nativeElement
Kinder vorhanden sind. Dies funktioniert möglicherweise nur mitencapsulation: ViewEncapsulation.Native
.Wickeln Sie das
<ng-content>
Tag ein und prüfen Sie, ob es Kinder hat. Das funktioniert nicht mitencapsulation: ViewEncapsulation.Native
.und überprüfen Sie, ob es Kinder hat
(nicht getestet)
quelle
@ViewChild
. Während "Legal", sollte ViewChild nicht für den Zugriff auf untergeordnete Knoten innerhalb einer Vorlage verwendet werden. Dies ist ein Antimuster, da Eltern zwar etwas über Kinder wissen , sie sich jedoch nicht an sie koppeln sollten , da dies normalerweise zu einer pathologischen Kopplung führt . Eine geeignetere Form des Datentransports oder der Bearbeitung von Anforderungen ist die Verwendung ereignisgesteuerter Methoden .@ViewChild
. Vielen Dank, dass Sie meinen Kommentaren etwas Ausgewogenheit verliehen haben. Ich finde unsere beiden Kommentare genauso erwägenswert wie die anderen.@ViewChild()
vom Namen. "Kinder" sind nicht unbedingt Kinder, sie sind nur der deklarative Teil der Komponente (wie ich es sehe). Wenn es sich bei den für dieses Markup erstellten Komponenteninstanzen um Zugriffe handelt, ist dies natürlich eine andere Geschichte, da hierfür zumindest Kenntnisse über die öffentliche Schnittstelle erforderlich wären und dies tatsächlich zu einer engen Kopplung führen würde. Dies ist eine sehr interessante Diskussion. Es macht mir Sorgen, dass ich nicht genug Zeit habe, um über solche Dinge nachzudenken, weil bei solchen Frameworks zu oft Zeit verbrannt wird, um überhaupt einen Weg zu finden.Wenn Sie einen Standardinhalt anzeigen möchten, verwenden Sie nicht einfach den Selektor "Nur Kind" von CSS.
https://www.w3schools.com/cssref/sel_only-child.asp
für zB: HTML
CSS
quelle
In meinem Fall muss ich Eltern von leeren ng-Inhalten verstecken:
Einfache CSS funktioniert:
quelle
Ich habe eine Lösung mit @ContentChildren Decorator implementiert , die der Antwort von @ Lerner irgendwie ähnlich ist.
Laut Docs hat dieser Dekorateur:
Der erforderliche Code in der übergeordneten Komponente lautet also:
In der Komponentenklasse:
Dann in der Komponentenvorlage:
Vollständiges Beispiel : https://stackblitz.com/edit/angular-jjjdqb
Ich habe diese Lösung in Winkelkomponenten, implementiert gefunden
matSuffix
, in der Form-Feld - Komponente.In der Situation, in der der Inhalt der Komponente später nach der Initialisierung der App eingefügt wird, können wir auch eine reaktive Implementierung verwenden, indem wir das
changes
Ereignis abonnierenQueryList
:Vollständiges Beispiel : https://stackblitz.com/edit/angular-essvnq
quelle
Mit Angular 10 hat es sich leicht geändert. Sie würden verwenden:
quelle