2016-03-14 31 views
20

Ho la seguente direttiva (TextElementDirective), che ha 4 variabili di input colorHex, fontFamily, fontWeight, fontStyle. Voglio impostare il colore e lo stile di un elemento usando questa direttiva.I valori di input della direttiva attributo angolare 2 non sono definiti e non sono impostati correttamente

@Directive(
{ 
    selector: "[text-element-map]", 
    // host: { 
    //  '(mousemove)': "onMouseMove()" 
    // } 
} 
) 

export class TextElementDirective{ 
@Input() colorHex : string; 
@Input() fontFamily : string; 
@Input() fontWeight : string; 
@Input() fontStyle : string; 

constructor(private el: ElementRef){ 
    this.setElement(); 
} 

setElement(){ 
    if(this.colorHex){ 
     this.el.nativeElement.style.color = this.colorHex; 
    } 
    if(this.fontFamily){ 
     this.el.nativeElement.style.fontFamily = this.fontFamily; 
    } 
    if(this.fontWeight){ 
     this.el.nativeElement.style.fontWeight = this.fontWeight; 
    } 
    if(this.fontStyle){ 
     this.el.nativeElement.style.fontStyle = this.fontStyle || ""; 
    } 
} 

onMouseMove(){ 
    this.setElement(); 
} 
} 

Quando uso questa direttiva in un altro componente, come attributo, non imposta lo stile e il colore dell'elemento. Anche se fai clic sul pulsante, i valori dell'elemento non sono impostati.

Se utilizzo un host (onmousemove) nella direttiva, funziona correttamente. Ma voglio impostare i valori durante l'avvio.

Qualche idea di cosa mi manca?

Ecco il componente di test che lo utilizza.

@Component({ 
template: 
` 
    <h3>Test</h3> 
    <div> 
     <span>text-element-map: </span> 
     <span class="text-content" text-element-map [colorHex]="colorHex" 
      [fontFamily]="fontFamily" [fontWeight]="fontWeight" [fontStyle]="fontStyle">Change this text</span> 

     <button (click)="setCurrentDesignElement()">Click</button> 
    </div> 
`, 
directives:[TextElementDirective], 
changeDetection: ChangeDetectionStrategy.Default 
}) 
export class TestComponent{ 

@ViewChild(TextElementDirective) 
private childTextElement: TextElementDirective; 


colorHex: string = "#e2e2e2"; 
fontFamily: string = "Arial"; 
fontWeight: string = "normal"; 
fontStyle: string = "normal"; 

setCurrentDesignElement(){ 
    this.color = { 
     hex: "#B4B4B4", 
     id: 5745, 
     name: "Athletic Heather" 
    }; 

    this.font = { 
     cssString: "Valera Round", 
     weight: "normal", 
     style: "italic" 
     }; 

    this.colorHex = "#B4B4B4"; 
    this.fontFamily = "Valera Round"; 
    this.fontWeight = "normal"; 
    this.fontStyle = "italic";  

    //this.childTextElement.setElement(); 
} 


} 

risposta

33

Input() s non sono disponibili nel costruttore. Sono impostati dal rilevamento delle modifiche e il rilevamento delle modifiche viene eseguito dopo l'istanza del componente. I ganci ciclo di vita ngOnChanges (ogni aggiornamento) e ngOnInit (una volta dopo il primo ngOnChanges chiamata) sono chiamati dopo rivelazione del cambiamento aggiornato un ingresso:

Change

constructor(private el: ElementRef){ 
    this.setElement(); 
} 

a

constructor(private el: ElementRef); 

ngOnInit() { 
    this.setElement(); 
} 

ngOnInit() è chiamato dopo che gli input sono inizializzati.


Invece di

this.el.nativeElement.style.color = this.colorHex; 

è meglio usare

@HostBinding('style.color') 
@Input() colorHex : string; 

@HostBinding('style.font-family') 
@Input() fontFamily : string; 

@HostBinding('style.font-weight') 
@Input() fontWeight : string; 

@HostBinding('style.font-style') 
@Input() fontStyle : string; 

In realtà io non mi sono provato ad aggiungere @HostBinding() e @Input() sullo stesso campo, ma non vedo perché non avrebbe funzionato

+0

Funziona quando la direttiva è inizializzata. Ma quando clicco sul pulsante per ripristinare colorHex, fontFamily, ecc. Non resetta il testo. Come posso assicurarmi che il setElement() venga chiamato quando il modello cambia? Perché il rilevamento dei cambiamenti non sta prendendo il sopravvento? –

+1

Ci sono due modi: rendere 'colorHex', ... setter e getter o cambiare' ngOnInit() 'in' ngOnChanges (changes) '. 'ngOnChanges' viene chiamato ogni volta che cambiano i valori di input. Con il mio suggerimento sopra non dovresti assolutamente aver bisogno di 'setElement()'. –

+0

Sì. Hai ragione. Quando utilizzo HostBinding, non ho bisogno della funzione setElement. Molte grazie. –