2016-07-16 15 views
5

Chciałbym uzyskać dostęp do zawartości ng-content, na początek wystarczy, aby uzyskać liczbę elementów treści, ale z większą awesomeness później.Jak uzyskać dostęp do zawartości Ng?

Na przykład:

@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); 
    } 
} 

Co mogę umieścić jako typ dla dzieci treści?

Mogą to być cokolwiek. Próbowałem ElementRef, ale to nie działało i zawsze dawało zero.

Przykład zastosowania:

<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> 

ja spodziewać się 'po zawartości INIT: 4'.

+0

Czy elementy podrzędne Angular2, które kontrolujesz (tj. chcesz uzyskać dostęp do instancji składnika)? Lub po prostu HTML? – Sjoerd

+0

Sjoerd, może być miksem. Spodziewam się losowego html, ale oczekuję również komponentów. A kiedy są komponentami, byłyby innego rodzaju. – Richard

Odpowiedz

4

Ja źle zrozumiałem @ContentChildren. To nie reprezentuje całej treści. Reprezentuje @Components w zawartości ng.

Aby bezpośrednio odpowiedzieć na pytanie:

nadal nie jest jasne, jak chciałbym nabyć @Components wewnątrz ng zawartości, jeśli nie wiem, ich typy wyprzedzeniem. Ale zdaję sobie sprawę, że to było trochę głupie: jeśli nie wiem, co to jest, co dokładnie mam zamiar z nimi zrobić?

pośrednio odpowiedzieć na pytanie:

dostępu do wszystkich treści ng zawartości mogę wprowadzenia Zmienna szablonu (#items) do nadrzędnego NG-treści i odniesienia, które poprzez @ViewChild jako elementRef . Następnie dzieci mogą być liczone w ten sposób:

@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); 
    } 
} 

Dla innych stojących podobnego zamieszania, mogę rozwinąć @ContentChildren nieco więcej. Że mam 2 @Components: Składnik-A i składnik-b i wiem, że konsument będzie umieścić je wewnątrz treść mojej części:

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

potem w moim składnika mogę nabyć odniesień do wszystkich wystąpień poszczególne rodzaje elementów:

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); 
    } 
} 

a konsola pokaże, że istnieją 2 składnika a i 1 komponent B.

muszę podkreślić, że jest to w release candidate 4.

+0

Aby dodać do części '@ ContentChildren': składniki mogą mieć wspólną klasę podstawową. Następnie można wybrać komponenty na podstawie ich typu podstawowego i wywołać dowolną metodę w typie podstawowym w instancji składnika. – Sjoerd

+0

Musisz odpowiednio skonfigurować dostawców, aby funkcja '@ContentChildren()' działała z klasami podstawowymi. To nie działa domyślnie. Dodając 'providerów: [{provide: BaseClass, useClass: SubClass}]' powinno działać ale wymaga to, aby wszystkie podklasy były znane z góry. –

Powiązane problemy