Communication between custom directive and component in Angular2
You can create an @Input() someName: SomeType
in your directive and bind it to a field or function in the parent component like
<div [mySelectedColor]="color"
[someName]="someFieldInParent"> I'm {{color}} color </div>
Another way is to query the directive in the parent component and invoke functions or set fields directly.
export class AppComponent{
@ViewChild(selectedColorDirective) myDirective: selectedColorDirective;
ngAfterViewInit() {
myDirective.changeColor('red');
}
}
You can also bind directly to class
and assign CSS by using these class selectors.
See for example this http://plnkr.co/edit/nm8RgxMtqdEDyQWQGeUp?p=preview
Using a binding as selector at the same time is not supported currently, therefore you have to list the directive selector and the property you bind to each. Only [(myDirective)]="someField"
seems to be supported.
I used
host: {
'(keyup)': 'changeColor()',
'[style.color]': 'selectedColor', // <==
}
for setting the style (I also changed the AppComponent
to use this way). This is preferred to using ElementRef
and Renderer
. I used ElementRef
and Renderer
for the <span>
tag though because I don't see another way from the directive on another element.
nyks
Updated on June 15, 2022Comments
-
nyks almost 2 years
I have a template which has textbox, one 'span' tag and one 'div' tag.
'div' tag has 'selectedColor' custom directive. I want to change background color of 'span' and 'div' tags when input value is changed.
So finally I want my directive to react on input change and sets background color of 'div' tag.
I also want to change 'span' background color on input value change event.
boot.ts
import {Component,bind} from 'angular2/core'; import {bootstrap} from 'angular2/platform/browser'; import {FORM_DIRECTIVES} from 'angular2/form'; import {selectedColorDirective} from 'src/directive'; import {Directive, ElementRef, Renderer, Input} from 'angular2/core'; @Component({ selector: 'my-app', template: ` <input type="text" [(ngModel)]="color" /> <br> <span > I'm {{color}} color <span> <div [mySelectedColor]="color"> I'm {{color}} color </div> `, directives: [selectedColorDirective] }) export class AppComponent{ color:string; constructor(el:ElementRef,renderer:Renderer) { this.color="Yellow"; renderer.setElementStyle(el, 'backgroundColor', this.color); } } bootstrap(AppComponent, []);
directive.ts
import {Directive, ElementRef, Renderer, Input} from 'angular2/core'; @Directive({ selector:"[mySelectedColor]", host: { // '(keyup)': 'changeColor()', '(blur)': 'changeColor()', } }) export class selectedColorDirective{ @Input('mySelectedColor') selectedColor: string; constructor(el: ElementRef, renderer: Renderer) { //el.nativeElement.style.backgroundColor = 'yellow'; renderer.setElementStyle(el, 'backgroundColor', this.selectedColor); } changeColor(color:string) { console.log('Changed Detection' + " " + selectedColor); //this.renderer.setElementStyle(this.el, 'backgroundColor', this.color); } }
Moreover if you could explain more about @Input decorator.
-
nyks over 8 yearsI want to do it through custom directive only to explore more about it.
-
Vlado Tesanovic over 8 yearsThis should be constructor of directive. For your span, you can use *ngStyle to set background on current value of color var
-
Günter Zöchbauer over 8 yearsModifying an element
<span>
from a directive that is added to another tag is IMHO a pretty bad idea. Is that really what you want? -
nyks over 8 yearsAnswer is great. but how can I call changeColor function written in directive when I change component's input field value and change bgcolor with ElementRef and Rendrer? is it possible?
-
Günter Zöchbauer over 8 yearsWhat do you mean by "call"? You don't want to use binding but directly call the method? Like shown here stackoverflow.com/questions/34846048/… ?
-
Günter Zöchbauer over 8 yearsNot sure if this is what you want plnkr.co/edit/QUf67I6qsQYk7n2gQAI9?p=preview I added a binding for the
blur
event (<input type="text" [(ngModel)]="color" (blur)="changeColor()" />
) and I added the binding toselectedColor
(<div mySelectedColor > (div) I'm {{color}} color </div>
) because otherwise the binding and the background color set by the function call interfere. I also changedchangeColor
to set the color passed as argument instead of the one bound toselectedColor
. Hope this helps. -
Ng2-Fun about 7 years@GünterZöchbauer - hey, do you know how to call the component class method when I was inside its directive?
-
Adrian over 5 yearsit's about directive communication instead of a specific directive type implementation, right?