2016-03-31 3 views

risposta

58

È possibile utilizzare exportAs proprietà della @Directive annotazione. Esporta la direttiva da utilizzare nella vista principale. Dalla vista principale, è possibile associarlo a una variabile di visualizzazione e accedervi dalla classe padre utilizzando @ViewChild().

esempio con un plunker:

@Directive({ 
    selector:'[my-custom-directive]', 
    exportAs:'customdirective' //the name of the variable to access the directive 
}) 
class MyCustomDirective{ 
    logSomething(text){ 
    console.log('from custom directive:', text); 
    } 
} 

@Component({ 
    selector: 'my-app', 
    directives:[MyCustomDirective], 
    template: ` 
    <h1>My First Angular 2 App</h1> 

    <div #cdire=customdirective my-custom-directive>Some content here</div> 
    ` 
}) 
export class AppComponent{ 
    @ViewChild('cdire') element; 

    ngAfterViewInit(){ 
    this.element.logSomething('text from AppComponent'); 
    } 
} 

Aggiornamento

Come accennato nei commenti, c'è un'altra alternativa al metodo di cui sopra.

Invece di usare exportAs, si potrebbe usare direttamente @ViewChild(MyCustomDirective) o @ViewChildren(MyCustomDirective)

Ecco il codice per dimostrare la differenza tra i tre approcci:

@Component({ 
    selector: 'my-app', 
    directives:[MyCustomDirective], 
    template: ` 
    <h1>My First Angular 2 App</h1> 

    <div my-custom-directive>First</div> 
    <div #cdire=customdirective my-custom-directive>Second</div> 
    <div my-custom-directive>Third</div> 
    ` 
}) 
export class AppComponent{ 
    @ViewChild('cdire') secondMyCustomDirective; // Second 
    @ViewChildren(MyCustomDirective) allMyCustomDirectives; //['First','Second','Third'] 
    @ViewChild(MyCustomDirective) firstMyCustomDirective; // First 

} 

Aggiornamento

Another plunker with more clarification

+4

La risposta è ottima. Ma questo può anche essere fatto senza 'cdire' direttamente come, elemento' @ViewChild (MyCustomDirective): MyCustomDirective; 'Quindi, in' ngAfterViewInit - this.element.logSomething ('text from ...') '. Quindi perché il tuo approccio quando direttamente semplicemente passando il tipo puoi farlo? Solo per i chiarimenti. – micronyks

+5

@micronyks Il tuo approccio è buono. tuttavia, presuppone che ci sia solo un 'MyCustomDirective'. Se ci sono più direttive, corrisponderà alla prima. Tuttavia, quando si utilizza "exportAs", è possibile specificarne uno in particolare, ad esempio il secondo 'MyCustomDirective'. – Abdulrahman

+2

L'utilizzo di una variabile modello semplifica l'evidenziazione di un singolo elemento se il modello contiene più di uno che altrimenti corrisponderebbe. Dipende sempre da ciò che effettivamente cerchi di realizzare e dalla tua situazione. Se vuoi ottenere tutto allora dovresti usare anche '@ViewChildren()' –

9

Sembra che, dal momento che la risposta di @ Abdulrahman, non è più possibile accedere alle direttive da @ViewChild o @ViewChildren poiché questi passano solo elementi sull'elemento DOM stesso.

Invece, è necessario accedere alle direttive utilizzando @ContentChild/@ContentChildren.

@Component({ 
    selector: 'my-app', 
    template: ` 
    <h1>My First Angular 2 App</h1> 

    <div my-custom-directive>First</div> 
    <div #cdire=customdirective my-custom-directive>Second</div> 
    <div my-custom-directive>Third</div> 
    ` 
}) 
export class AppComponent{ 
    @ContentChild('cdire') secondMyCustomDirective; // Second 
    @ContentChildren(MyCustomDirective) allMyCustomDirectives; //['First','Second','Third'] 
    @ContentChild(MyCustomDirective) firstMyCustomDirective; // First 
} 

C'è anche non è più una proprietà directives su attributi @Component.

+5

Le istanze create con @ContentChild non sono definite. Perché ? Ad esempio, all'interno di una funzione componente 'this.firstMyCustomDirective' è' indefinito' –

+2

ContentChild o ViewChild non sembrano funzionare e restituiscono una variabile indefinita – ninja

+1

https://stackoverflow.com/questions/34326745/whats-the-difference-between -viewchild-and-contentchild Penso ci siano dei malintesi. – maxisam

Problemi correlati