2016-01-30 11 views
39

Supponiamo che io sono un componente:In Angular 2 come verificare se <ng-content> è vuoto?

@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 { 
} 

Ora, vorrei visualizzare alcuni contenuti di default se <ng-content> per questo componente è vuoto. C'è un modo semplice per farlo senza accedere direttamente al DOM?

+1

Eventuali duplicati di [Come verificare se esiste ng-content] (https://stackoverflow.com/questions/38692881/how-to-check-whether-ng -content-exists) – titusfx

+0

FYI, so che la risposta accettata funziona, ma penso che sia meglio che lo stile passi un parametro di input di tipo "useDefault" ai componenti, impostato su false. – bryan60

risposta

48

Wrap ng-content in un elemento HTML come un div per ottenere un riferimento locale ad esso, quindi associare il ngIf espressione a ref.children.length == 0:

template: `<div #ref><ng-content></ng-content></div> 
      <span *ngIf="ref.children.length == 0"> 
       Display this if ng-content is empty! 
      </span>` 
+8

Non c'è un modo alternativo a questo? Perché questo è brutto, rispetto alle slot di fallback di Aurelia – Astronaut

+7

È più sicuro usare "ref.children.length". childNodes conterrà i nodi 'text' se si formatta l'html con spazi o nuove linee, ma i bambini saranno ancora vuoti. – parliament

+4

Esiste una richiesta di funzionalità per un metodo migliore sul rilevatore di problemi Angular: https://github.com/angular/angular/issues/12530 (potrebbe valere la pena aggiungere un +1 lì). – eppsilon

3

Iniettare elementRef: ElementRef e verificare se elementRef.nativeElement ha bambini. Questo potrebbe funzionare solo con encapsulation: ViewEncapsulation.Native.

Avvolgere il tag <ng-content> e verificare se ha bambini. Questo non funziona con encapsulation: ViewEncapsulation.Native.

<div #contentWrapper> 
    <ng-content></ng-content> 
</div> 

e verificare se ha dei figli

@ViewChild('contentWrapper') contentWrapper; 

ngAfterViewInit() { 
    contentWrapper.nativeElement.childNodes... 
} 

(non testato)

+1

L'ho downvoted a causa dell'uso di '@ ViewChild'. Mentre "Legal", ViewChild non dovrebbe essere usato per accedere ai nodi figlio all'interno di un modello. Questo è un antipattern perché, mentre i genitori possono sapere sui bambini, non dovrebbero * Coppia * a loro come di solito porta a ** Accoppiamento patologico **; una forma più appropriata di trasporto dei dati o gestione delle richieste è quella di utilizzare ** metodologie basate sugli eventi **. – Cody

+0

Perché non esiste una strategia dichiarativa basata su modelli per realizzare questo? L'approccio intuitivo, in particolare dal punto di vista della cronologia di Angular (1.x), consiste nel nidificare il contenuto predefinito in "" e consentirne la sovrascrittura se qualcosa viene proiettato/escluso. Sembra, tuttavia, che Angular abbia esplicitamente negato tale efficacia: che peccato. – Cody

+1

@Cody, grazie per aver postato un commento al tuo downvote. In realtà io non seguo le tue argomentazioni. Il modello e la classe dei componenti sono una singola unità, un componente. Non vedo perché l'accesso al modello dal codice dovrebbe essere un antipattern. Angular (2/4) non ha quasi nulla in comune con AngularJS tranne che entrambi sono framework web e il nome. –

0

Alcuni mancano nella risposta @pixelbits. Dobbiamo verificare non solo la proprietà children, perché qualsiasi interruzione di linea o spazi nel modello principale causerà l'elemento children con testo \ interruzioni di riga vuote. Meglio controllare .innerHTML e .trim() it.

esempio di lavoro:

<span #ref><ng-content></ng-content></span> 
<span *ngIf="!ref.innerHTML.trim()"> 
    Content if empty 
</span> 
Problemi correlati