使用 formArray 时出现 Mat-AutoComplete 错误
Mat-AutoComplete error when using formArray
我添加了一个 formarray 来说明多行。为了使它与索引一起工作,我必须将我的定义从 shoppingCartList Observable<any[]>;
更改为 shoppingCartList: Observable<any[]>[] = [];
但是当我这样做时它会在我的过滤器函数中抛出一个错误 missing the following properties from type 'Observable<any[]>[]': length, pop, push, concat
。看起来是因为我正在调用一项服务来过滤列表。实现这个的正确方法是什么:
.HTML
<mat-autocomplete #auto="matAutocomplete" [displayWith]="entry">
<mat-option *ngFor="let case of shoppingCartList[i] | async" [value]="case">
{{title}}
</mat-option>
</mat-autocomplete>
.TS
shoppingCartList: Observable<any[]>[] = [];
this.shoppingCartList[index] = arrayControl.at(index).get('name').valueChanges //ERROR: (property) DraftformComponent.filteredPrimaryCaseSerial: Observable<any[]>[]
Type 'Subscription' is missing the following properties from type 'Observable<any[]>
.pipe(debounceTime(this.debounceTime))
.subscribe(
(val) => {
this.filteredList= this.getFilteredlist(val); //ERROR: (property) DraftformComponent.filteredPrimaryCaseSerial: Observable<any[]>[]
Type 'Observable<any[]>' is missing the following properties from type 'Observable<any[]>[]
}
);
public getFilteredList(val: string): Observable<any[]> {
return this.myService.getListByValue(val);
}
如果我正确地看到你的代码,你就订阅了 observable。因此,您在模板中获取的不是数组值,而是订阅。您应该删除 subscribe 方法以使模板正常工作,或者您将值保存在 subscribe 方法中并在没有可观察对象的情况下使用它。
我不完全理解您想对示例中的“filteredList”做什么,但是您可以将代码包装在 tap 运算符 https://rxjs.dev/api/operators/tap
中
首先,您看到错误的原因是您输入列表的方式。
Observable<any[]>[] = [];
你在这里告诉编译器你的购物车列表的类型是一个由多个 observables 数组组成的数组。
所以,错误 missing the following properties from type 'Observable<any[]>[]': length, pop, push, concat
只是告诉你,你所说的 getFilteredList
将 return 实际上不是函数所期望的 return --它期望 return 一个 数组的可观察对象 (任何类型)。
这与使用服务过滤列表无关。当您提到在这种情况下使用表单数组来解释多行时,我也有点不确定您的意思。
考虑到这一点 - 根据您的问题,我认为您的目标是这样的。
/**
* Define a form which contains your FormControl you wish
* to use for your autocomplete.
*/
form = new FormGroup({
shoppingListSearch: new FormControl()
});
像这样访问它:
get shoppingListSearch(): FormControl {
return this.form.get('shoppingListSearch') as FormControl;
}
FormControl
s 将它们的值变化公开为可观察的,方便地称为 valueChanges
。您的尝试已经走在了正确的轨道上!
与其手动订阅 observables,我会使用 Angular 的模板。它管理在销毁组件时为您整理订阅。如果您像上面那样手动订阅可观察对象,并且不取消订阅,您将留下订阅,导致内存泄漏。
像这样定义一个可观察对象:
filteredList$: Observable<
ShoppingListItem[]
> = this.shoppingListSearch.valueChanges.pipe(
debounceTime(1000),
// Use a switchMap here to subscribe to the inner observable.
// This is assuming your filtering needs to make a HTTP request.
// switchMap will maintain one inner subscription, so should you
// make another request while one is in flight, the in flight
// request will be cancelled and a new one made with your new
// search term.
switchMap((searchTerm: string) =>
// this can be whatever filtering logic you want I guess.
// To reiterate, I used a switchMap above as getFilteredList
// returns an observable. An operator like map or tap wouldn't
// work here, as they don't handle subscribing to inner observables.
this.myService.getFilteredList(searchTerm)
)
);
这是模板:
<form class="example-form" [formGroup]="form">
<mat-form-field appearance="fill">
<mat-label>Search...</mat-label>
<input
class="example-full-width"
placeholder="Search for something..."
formControlName="shoppingListSearch"
[matAutocomplete]="auto"
matInput
/>
</mat-form-field>
<mat-autocomplete #auto="matAutocomplete" [displayWith]="entry">
<!-- Here is where we subscribe to the filtered list observable -->
<mat-option *ngFor="let shoppingItem of filteredList$ | async" [value]="shoppingItem.name">
{{shoppingItem.name}}
</mat-option>
</mat-autocomplete>
</form>
这是 StackBlitz。
我添加了一个 formarray 来说明多行。为了使它与索引一起工作,我必须将我的定义从 shoppingCartList Observable<any[]>;
更改为 shoppingCartList: Observable<any[]>[] = [];
但是当我这样做时它会在我的过滤器函数中抛出一个错误 missing the following properties from type 'Observable<any[]>[]': length, pop, push, concat
。看起来是因为我正在调用一项服务来过滤列表。实现这个的正确方法是什么:
.HTML
<mat-autocomplete #auto="matAutocomplete" [displayWith]="entry">
<mat-option *ngFor="let case of shoppingCartList[i] | async" [value]="case">
{{title}}
</mat-option>
</mat-autocomplete>
.TS
shoppingCartList: Observable<any[]>[] = [];
this.shoppingCartList[index] = arrayControl.at(index).get('name').valueChanges //ERROR: (property) DraftformComponent.filteredPrimaryCaseSerial: Observable<any[]>[]
Type 'Subscription' is missing the following properties from type 'Observable<any[]>
.pipe(debounceTime(this.debounceTime))
.subscribe(
(val) => {
this.filteredList= this.getFilteredlist(val); //ERROR: (property) DraftformComponent.filteredPrimaryCaseSerial: Observable<any[]>[]
Type 'Observable<any[]>' is missing the following properties from type 'Observable<any[]>[]
}
);
public getFilteredList(val: string): Observable<any[]> {
return this.myService.getListByValue(val);
}
如果我正确地看到你的代码,你就订阅了 observable。因此,您在模板中获取的不是数组值,而是订阅。您应该删除 subscribe 方法以使模板正常工作,或者您将值保存在 subscribe 方法中并在没有可观察对象的情况下使用它。 我不完全理解您想对示例中的“filteredList”做什么,但是您可以将代码包装在 tap 运算符 https://rxjs.dev/api/operators/tap
中首先,您看到错误的原因是您输入列表的方式。
Observable<any[]>[] = [];
你在这里告诉编译器你的购物车列表的类型是一个由多个 observables 数组组成的数组。
所以,错误 missing the following properties from type 'Observable<any[]>[]': length, pop, push, concat
只是告诉你,你所说的 getFilteredList
将 return 实际上不是函数所期望的 return --它期望 return 一个 数组的可观察对象 (任何类型)。
这与使用服务过滤列表无关。当您提到在这种情况下使用表单数组来解释多行时,我也有点不确定您的意思。
考虑到这一点 - 根据您的问题,我认为您的目标是这样的。
/**
* Define a form which contains your FormControl you wish
* to use for your autocomplete.
*/
form = new FormGroup({
shoppingListSearch: new FormControl()
});
像这样访问它:
get shoppingListSearch(): FormControl {
return this.form.get('shoppingListSearch') as FormControl;
}
FormControl
s 将它们的值变化公开为可观察的,方便地称为 valueChanges
。您的尝试已经走在了正确的轨道上!
与其手动订阅 observables,我会使用 Angular 的模板。它管理在销毁组件时为您整理订阅。如果您像上面那样手动订阅可观察对象,并且不取消订阅,您将留下订阅,导致内存泄漏。
像这样定义一个可观察对象:
filteredList$: Observable<
ShoppingListItem[]
> = this.shoppingListSearch.valueChanges.pipe(
debounceTime(1000),
// Use a switchMap here to subscribe to the inner observable.
// This is assuming your filtering needs to make a HTTP request.
// switchMap will maintain one inner subscription, so should you
// make another request while one is in flight, the in flight
// request will be cancelled and a new one made with your new
// search term.
switchMap((searchTerm: string) =>
// this can be whatever filtering logic you want I guess.
// To reiterate, I used a switchMap above as getFilteredList
// returns an observable. An operator like map or tap wouldn't
// work here, as they don't handle subscribing to inner observables.
this.myService.getFilteredList(searchTerm)
)
);
这是模板:
<form class="example-form" [formGroup]="form">
<mat-form-field appearance="fill">
<mat-label>Search...</mat-label>
<input
class="example-full-width"
placeholder="Search for something..."
formControlName="shoppingListSearch"
[matAutocomplete]="auto"
matInput
/>
</mat-form-field>
<mat-autocomplete #auto="matAutocomplete" [displayWith]="entry">
<!-- Here is where we subscribe to the filtered list observable -->
<mat-option *ngFor="let shoppingItem of filteredList$ | async" [value]="shoppingItem.name">
{{shoppingItem.name}}
</mat-option>
</mat-autocomplete>
</form>
这是 StackBlitz。