Reputation: 51
I'm running into an issue where I can access locally declared variables in the component controller instantiating the mat-autocomplete. The problem I'm facing is the local variables are stuck in this scope and I can't update them.
Ultimately what I'm doing is concatenating the display string and a variable bound to the input model. This is giving me an autocomplete input that adds helper text for the user, ideally the text is up to date with clearing the input. The text is currently continuously concatenating, creating unusable text pretty quickly
html
<input
[(ngModel)]="filter>
mat-autocomplete
#auto="matAutocomplete"
[displayWith]="displayFn">
<mat-option
*ngFor="let option of filteredOptions | async"
[value]="option">
{{ option }}
</mat-option>
</mat-autocomplete>
component.ts
displayFn(search): string | undefined {
if(!search) return; //check if the search isn't already populated
if(!search.match(/(=|\*)/)){
if(this.filter){
this.filter += ' ' + search + '==*term*';
}else{
this.filter = search +'==*term*';
}
return this.filter; //this isn't persisting across the lifecycle
}
}
Upvotes: 4
Views: 4426
Reputation: 3587
You have two options, the first one is just calling [displayWith]="displayFn.bind(this)"
which looks weird in the Angular world, but I can confirm that it works (although I got an Error on my WebStorm saying ng: Unknow Method bind
)
And the second one is to use an arrow function in order to preserve the context.
Something like this:
displayFn(offer?: Offer): string | undefined {
return offer && offer.name == this.currentOffer.name ? offer.name : undefined;
}
displayFnWrapper() {
return (offer) => this.displayFn(offer);
}
And in the template:
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFnWrapper()" (optionSelected)='assign($event.option.value)'>
<mat-option *ngFor="let offer of filteredOffers$ | async" [value]="offer">{{ offer.name }}</mat-option>
</mat-autocomplete>
Upvotes: 13
Reputation: 421
If I use an example, MyClass, where
@Input() modeCity = false;
in ngOnInit() I can access the modeCity and change it. It is reflected over other methods in the class.
in HTML,
<mat-autocomplete #auto="matAutocomplete" autoActiveFirstOption [displayWith]="itemDisplayFn" (optionSelected)="selected($event)">
then for method itemDisplayFn(item: ..) in the ts file, the modeCity is undefined.
I found that somehow the method itemDisplayFn() has static context. Therefore I created the property,
static staticModeCity = false;
staticModeCity can be set in the ngOnInit() like so,
MyClass.staticModeCity = true
and used in the Method itemDisplayFn() like so,
if(MyClass.staticModeCity) ....
I do not know why this is. Of course static can be conflicting, if the same component is used multiple times in the same parent component.
Upvotes: 0