I have a very simple Angular attribute directive that looks something like this:
import { Directive, Input, OnInit } from "@angular/core";
@Directive({
selector: "[foo]",
})
export class FooDirective implements OnInit {
@Input() public foo: string;
public ngOnInit(): void {
// Do something here once
}
}
It will be used like this:
<div [foo]="bar"></div>
bar might be a simple string, but could also be a string getter that is relatively expensive to run.
I would therefore like to read the value once on initialization, but ignore it afterwards.
I know that the ngOnInit is only called once, but change detection will cause the bar property to be called repeatedly (depending on how the containing component works).
Using @Attributes would have been nice, since they only get evaluated once.
But it doesn't seem like @Attribute works for directives (with the same name?):
import { Directive, OnInit, Attribute } from "@angular/core";
@Directive({
selector: "[foo]",
})
export class FooDirective implements OnInit {
public constructor(
@Attribute("foo")
private readonly foo: string
) {}
public ngOnInit(): void {
// Do something with this.foo here
}
}
How do I avoid that the input property is evaluated more than once? I would prefer to unsubscribe from any changes, so to speak.
Directives don't seem to support ChangeDetectionStrategy.OnPush, but something similar could be nice.
ChangedetectorRef.detach(). However, this completely removes change detection and not only for the desiredInput(). I agree with the answer that this is not a problem a directive can solve.ChangeDetectorRef.detach()in this case detach change detection for? Is that the component where the attribute is use? Or just everywhere (whatever that might mean)?detaches this view. Basically, no change detection for the component or its children. you can use.detectChanges()to implement local change detection but... you can't do that from a directive alone either.