<mat-autocomplete>
from Angular Material(AngularJSではない))をリアクティブフォームを使用せずに使用しようとしていますが、すべての例でリアクティブフォームを使用しています...
私がやろうとしていること:
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
には何も設定されていないため、今は何もしません。
テンプレート内のメソッドの呼び出しは避ける必要があります。これにより、各変更検出で呼び出されるため、ブラウザーがクラッシュする可能性があります。 * ngangular2で無限ループを実行する場合 技術的には無限ループではありませんが、ポイントを取得:)
オートコンプリートでフォームコントロールを持たないことはそれほど変わりません。代わりにフォームコントロールを変数に交換するだけで、必要に応じてテンプレート駆動フォームを使用することも、フォームをまったく使用しないこともできます。ただし、テンプレート駆動型のフォームは次のとおりです。
これで使用されるデモ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))
}
サービスには変数があり、最初のフェッチ後にAPIデータを格納するため、各キーストロークでAPIを呼び出すことはありません。データが返されたら、変数が設定されているかどうかを確認し、設定されている場合は、そのオブザーバブルを返します:
jokes = [];
getData() {
return this.jokes.length ? of(this.jokes)
: this.httpClient.get<any>('https://api.icndb.com/jokes/random/5').pipe(
map((data) => {
this.jokes = data.value;
return this.jokes;
})
)
}
離れて移動する場合は、jokes
配列をクリアすることを忘れないでください。