Binding 'this' in Angular Material Autocomplete displayWith using Angular 5

我的梦境 提交于 2020-06-12 04:09:11

问题


I was trying to use the Material Angular autocomplete and I came across the displayWith function which can be apparently used to be the output that is displayed on selection. I wanted to call a custom function within the display function like

displayFn(id) {
 return this.getValue(id)
}
getValue(id) {
 /**return some string
}

For the autocomplete

<mat-autocomplete #autoOutlet="matAutocomplete" [displayWith]="displayFn">
  <mat-option *ngFor="let option of outletFilterOptions | async [value]="option.outletId">
   {{ option.outletName }}
  </mat-option>
</mat-autocomplete>

As you see I am using the id as the model instead of the entire object.

When the display function returned an error that this.getValue is undefined I searched Stack Overflow for a solution and was suggested that I use something like [displayWith]="displayFn.bind(this)".

But unfortunately, that isn't working for me either. I am using Angular material 5.1.0.

Is there something I am missing?


回答1:


displayFn = value => {
  // now you have access to 'this' 
  this.someMethod();
  return 'formatted display';
}



回答2:


You could just change your template to be

<mat-autocomplete #autoOutlet="matAutocomplete" [displayWith]="displayFn(id, this)">

Inside of templates this is a reference to your Component. Then just change your function to

displayFn(id, _this) {
  return _this.getValue(id)
}

If [displayWith] needs to be a function, you could create a property that returns your displayFn like this:

get createDisplayFn() {
  return (id) => {
    return this.getValue(id)
  }
}

and change your binding to [displayWith]="createDisplayFn". As ES6 arrow function can't be rebinded, this should still be a reference to your component.




回答3:


It is because of this is not binding to the component and its binding to mat-select option

NOw for using component's function, you have to use arrow function, the preferable method or pass this from the HTML function

I will use the arrow function to use the component's function

Without arrow function

displayFn(data: any) {
    return data.Id?this.sometask(data):''
}

With arrow function

displayFn = (data: any) => {
    return data.Id?this.sometask(data):''
}

This work in my scenario and it worked in your scenario too.




回答4:


Define cThis = this as a property of your class, and then use it inside your displayFn function:

<mat-autocomplete #autoOutlet="matAutocomplete" [displayWith]="displayFn(id, cThis)">


cThis = this;
displayFn(id, cThis) {
 return cThis.getValue(id)
}
getValue(id) {
 /**return some string
}

Demo that shows binding in displayWith




回答5:


You just missed an undefined check before using attribute.

<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn" (optionSelected)="optionSelected($event)">

<mat-option *ngFor="let user of users" [value]="user" >
    {{ user.first_name }} {{ user.last_name }}
</mat-option>

displayFn(user) {
    if (!user) return '';
    return user.name;
}   


来源:https://stackoverflow.com/questions/49939310/binding-this-in-angular-material-autocomplete-displaywith-using-angular-5

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!