2016-07-16 105 views
5

Vorrei accedere al contenuto di ng-content, per iniziare solo per ottenere un conteggio degli elementi di contenuto, ma con più meraviglie in seguito.Come accedo al contenuto di ng?

Ad esempio:

@Component({ 
selector: 'my-container', 
template: ` 
    <div class="my-container"> 
     <div class="my-container-nav"><a class="my-container-previous"></a></div> 
     <div class="my-container-body"> 
      <div class="my-container-items"> 
       <ng-content></ng-content> 
      </div> 
     </div> 
     <div class="my-container-nav"><a class="my-container-next"></a></div> 
    </div> 
` 
}) 
export class MyContainer implements AfterContentInit { 
    @ContentChildren(???) containerItems : QueryList<???>; 
    ngAfterContentInit() { 
     console.log('after content init: ' + this.containerItems.length); 
    } 
} 

Quello che faccio a mettere come tipo per i bambini di contenuti?

Potrebbero essere qualsiasi cosa. Ho provato ElementRef, ma non ha funzionato e ho sempre dato un conteggio pari a zero.

Esempio di utilizzo:

<my-container> 
    <div>some content here</div> 
    <another-component [title]="'another component there'"></another-component> 
    <div>there's lots of content everywhere</div> 
    <span>no assumptions would be fair</span> 
</my-container> 

mi sarei aspettato di vedere 'dopo il contenuto init: 4'.

+0

I componenti Angular2 dei bambini che controlli (ad es. vuoi accedere alle istanze del componente)? O semplicemente HTML? – Sjoerd

+0

Sjoerd, potrebbe essere un mix. Mi aspetto html casuale, ma mi aspetto anche componenti. E quando sono componenti, sarebbero di tipi diversi. – Richard

risposta

4

Ho frainteso @ContentChildren. Non rappresenta tutto il contenuto. Rappresenta @Components in ng-content.

Per rispondere direttamente alla domanda:

non è ancora chiaro come avrei acquisire @Components all'interno ng-contenuti, se non so i loro tipi prima del tempo. Ma ora mi rendo conto che è stato un po 'sciocco: se non so cosa sono, cosa penso esattamente che farò con loro?

Per rispondere indirettamente alla domanda:

di accedere a tutti i contenuti di NG-contenuti posso introdurre una variabile di modello (#items) nel genitore del ng-contenuti e di riferimento che via @ViewChild come elementRef . Poi i bambini possono essere contati in questo modo:

@Component({ 
selector: 'my-container', 
template: ` 
    <div class="my-container"> 
     <div class="my-container-nav"><a class="my-container-previous"></a></div> 
     <div class="my-container-body"> 
      <div #items class="my-container-items"> 
       <ng-content></ng-content> 
      </div> 
     </div> 
     <div class="my-container-nav"><a class="my-container-next"></a></div> 
    </div> 
` 
}) 
export class MyContainer implements OnInit { 
    @ViewChild('items') items: ElementRef; 
    ngOnInit() { 
     console.log('count is: ' + this.items.nativeElement.children.length); 
    } 
} 

Per altri di fronte confusione simile, è possibile espandere su @ContentChildren un po 'più. Dire che ho 2 @Components: componente A e il componente-b e so che consumatore posizionare questi all'interno del contenuto della mia componente:

<my-component> 
    <component-a></component-a> 
    <div>random html</div> 
    <component-b></component-b> 
    <component-a></component-a> 
</my-component> 

Poi nel mio componente posso acquisire i riferimenti a tutte le istanze della i singoli tipi di componenti:

export class MyContainer implements AfterContentInit { 
    @ContentChildren(ComponentA) componentAInstances: QueryList<ComponentA>; 
    @ContentChildren(ComponentB) componentBInstances: QueryList<ComponentB>; 
    ngAfterContentInit() { 
     console.log('count of component A: ' + this.componentAInstances.length); 
     console.log('count of component B: ' + this.componentBInstances.length); 
    } 
} 

e la console sarà mostrare che ci sono 2 componenti a e 1 componente B.

Tengo a precisare che questo è alla release candidate 4.

+0

Per aggiungere alla parte '@ ContentChildren': i componenti potrebbero condividere una classe base comune. È quindi possibile selezionare i componenti in base al loro tipo di base e richiamare qualsiasi metodo nel tipo di base sull'istanza del componente. – Sjoerd

+0

È necessario impostare correttamente i provider per far sì che '@ContentChildren()' funzioni con le classi di base. Questo non funziona per impostazione predefinita. Aggiungendo 'providers: [{provide: BaseClass, useClass: SubClass}]' dovrebbe funzionare, ma richiede che tutte le sottoclassi siano conosciute in anticipo. –