简体   繁体   中英

Material.Angular.io mat-autocomplete [displayWith] function update scope variables

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.

Any ideas or thoughts on updating the mat-autocomplete scope variables.

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
    }
  }

You have two options, the first one is just calling [displayWith]="displayFn.bind(this)" which looks awful but I can confirm that this 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>

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM