使用 formArray 时出现 Mat-AutoComplete 错误 [英] Mat-AutoComplete error when using formArray

查看:22
本文介绍了使用 formArray 时出现 Mat-AutoComplete 错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我添加了一个 formarray 来说明多行.为了使它与索引一起工作,我不得不将我的定义从:shoppingCartList Observable; 更改为 shoppingCartList: Observable[] = []; 但是,当我这样做时,它会在我的过滤器函数中抛出一个错误,说 缺少类型 'Observable[]' 中的以下属性:length、pop、push、concat.看起来是因为我正在调用服务来过滤列表.实现此目的的正确方法是什么:.HTML

I added a formarray to account for multiple rows. In order to make it work with the index I had to change my definition from : shoppingCartList Observable<any[]>; to shoppingCartList: Observable<any[]>[] = []; however when I do that it throws an error in my filter function saying missing the following properties from type 'Observable<any[]>[]': length, pop, push, concat. it looks like it's because I am calling a service to filter a list. What is the correct way to implement this: .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);
          }

推荐答案

首先,您看到错误的原因是您输入列表的方式.

Firstly, the reason you are seeing the error you are seeing is because of the way you've typed your list.

Observable[] = [];

您已经在这里告诉编译器您的购物车列表的类型是由多个可观察对象组成的数组.

You've told the compiler here that the type of your shopping cart list is an array of multiple arrays of observables.

所以,错误 missing the following properties from type 'Observable[]': length, pop, push, concat 只是告诉你你在说什么 getFilteredList 将返回的实际上并不是函数期望返回的——它期望返回一个数组的可观察对象(任何类型).

So, the error missing the following properties from type 'Observable<any[]>[]': length, pop, push, concat is just telling you that what you are saying getFilteredList will return is not actually what the function is expecting to return -- it's expecting to return an observable of an array (of any type).

这与使用服务过滤列表无关.我也有点不确定当您提到在此上下文中使用表单数组来说明多行时的意思.

It isn't anything to do with using a service to filter a list. I am also a bit unsure by what you mean when you refer to using a form array to account for multiple rows in this context.

考虑到这一点 - 根据您的问题,这就是我认为您的目标.

With that in mind - here's what I think you are aiming for based on your question.

  /**
   * 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 将它们的值更改公开为可观察的,方便地称为 valueChanges.您的尝试已经走在正确的轨道上!

FormControls expose their value changes as an observable, handily called valueChanges. You already are on the right track in your attempt!

我会为此使用 Angular 的模板,而不是手动订阅 observable.它在组件销毁时为您管理订阅的整理.如果你像上面那样手动订阅 observables,并且没有取消订阅,你会留下订阅,导致内存泄漏.

Rather than manually subscribing to observables, I would use Angular's templates for this. It manages the tidying up of subscriptions for you on destroy of the component. If you manually subscribe to observables as you have done above, and don't unsubscribe, you will leave subscriptions lying around, leading to memory leaks.

像这样定义一个 observable:

Define an observable like so:

  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 时出现 Mat-AutoComplete 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆