在没有ReactiveForm的情况下使用Angular Material mat-autocomplete

时间:2018-01-29 14:29:49

标签: angular angular-material2 mat-autocomplete

我尝试使用Angular Material(而不是AngularJS)中的<mat-autocomplete>而不使用反应形式。但他们所有的例子都使用了反应形式......

我尝试做什么:
1.当在mat-input中输入内容时,进行Ajax调用以检索用户列表 2.显示自动填充中的用户列表(显示用户名称),但将用户存储为模型
3.当模型改变时,调用我选择的函数

现在我做那些疯狂的事情(我说疯了似乎很多)。

<mat-form-field fxLayout>
  <input type="text"
             matInput fxFlex="100"
             [(ngModel)]="listFilterValue"
             (keyup)="memberInputChanged(input.value)"
             (change)="memberChanged()"
             *ngIf="isAutocompleteNeeded()"
             #input
             [matAutocomplete]="auto">
</mat-form-field>

<mat-autocomplete #auto="matAutocomplete" [displayWith]="getMemberAsStr">
       <mat-option *ngFor="let member of members | async" [value]="member">
          {{ getMemberAsStr(member) }}
       </mat-option>
</mat-autocomplete>

目前,我的JS中只有console.log来查看所谓的内容,具有什么价值,所以我不在这里分享。我使用正确的属性,正确的逻辑吗?

(我的组件中的members属性是Rxjs BehaviourSubject)

我现在所做的事情不起作用,因为listFilterValue永远不会被设置为任何东西。

感谢您的帮助

1 个答案:

答案 0 :(得分:13)

你应该避免在模板中调用方法,这可能会使你的浏览器在每次更改检测时被调用时崩溃,请参阅:*ngFor running an infinite loop in angular2从技术上讲,它不是一个无限循环,但你明白了这一点:)

至于没有自动完成的表单控件没有太大的不同,你只需将表单控件交换为变量,如果需要,可以使用模板驱动的表单,或者根本不使用表单。这里是模板驱动的形式:

这里使用的演示JSON如下所示:

"value": [
  {
    "id": 409,
    "joke": "some joke here",
    "categories": []
  }
]
<form #f="ngForm">
  <mat-form-field>
    <input matInput [matAutocomplete]="auto" 
           name="joke" #jokeField="ngModel" 
           [(ngModel)]="currentJoke" (ngModelChange)="doFilter()">
  </mat-form-field>

  <mat-autocomplete #auto="matAutocomplete">
    <mat-option *ngFor="let joke of jokes | async" [value]="joke.joke">
        {{joke.joke}}
    </mat-option>
  </mat-autocomplete>
</form>

你的TS可能看起来像:

doFilter() {
  this.jokes = this.service.getData()
    .pipe(
      map(jokes => this.filter(jokes.value)),
  )
}

filter(values) {
  return values.filter(joke => 
    // used 'includes' here for demo, you'd want to probably use 'indexOf'
    joke.joke.toLowerCase().includes(this.currentJoke))
}

<强> StackBlitz Demo