Reputation: 687
I'm implementing a directive that takes a language (or a set of languages) as input and adds a class to the DOM element where the directive was added.
@Directive({
selector: '[appRtlView]'
})
export class RTLViewDirective implements OnInit, OnChanges {
@Input('appRtlView') inputLanguage: string | string[];
constructor(private el: ElementRef) {}
ngOnInit() {
this.handleRtl();
}
private handleRtl() {
if (this.inputLanguage) {
let languageList = null;
if (!Array.isArray(this.inputLanguage)) {
languageList = [this.inputLanguage];
} else {
languageList = this.inputLanguage;
}
// both conditions do stuff with this.el.nativeElement.classList
if (languageList.includes('ar')) {
this.addRtl();
} else {
this.removeIfRtlExists();
}
}
}
}
Below is where I use the directive. "languagesInView" is a list of strings, ingested in the component that uses this directive using @Input() ...
<div *ngIf="concept">
<div class="concept-header" [appRtlView]="languagesInView">
...
</div>
</div>
I expect that when the languagesInView input that is passed into the component changes, the value that I pass to [appRtlView] in the template would change. (I can see that the value actually changes by printing the value to the screen using interpolation {{ languagesInView }})
In the RTLView directive, if I use ngOnInit, the changes to the "inputLanguage" field are not picked up.
To overcome this, I'm using ngOnChanges in the directive (implementing OnChanges does what I want):
// ngOnInit added because Angular doesn't accept a directive without an OnInit implementation
ngOnInit() {}
ngOnChanges(change: SimpleChanges) {
// TODO: A check to see if the input value has changed or not would help performance
this.handleRtl();
}
I wasn't able to add a changeDetectionStrategy to the directive initialization, and this made me think that a directive normally isn't supposed to be implementing OnChanges. My online search didn't help a lot.
Is it wrong to have ngOnChanges run in an Angular directive?
Thanks
Upvotes: 1
Views: 5846
Reputation: 687
I think I have my answer, from the lifecycle hooks documentation. My question came down to whether I could use/should be using ngOnChanges in a directive. The bolded line was pretty much what I needed.
Lifecycle Hooks
A component has a lifecycle managed by Angular.
Angular creates it, renders it, creates and renders its children, checks it when its data-bound properties change, and destroys it before removing it from the DOM.
Angular offers lifecycle hooks that provide visibility into these key life moments and the ability to act when they occur.
A directive has the same set of lifecycle hooks.
Thanks to everyone who responded.
Upvotes: 0
Reputation: 1943
ngOnChanges
only runs when the Input change comes from a template binding like <component [someInput]="aValue">
.
There are a couple ways to resolve this.
ngOnChanges
would do.ChangeDetectorRef
.Upvotes: 0