简体   繁体   English

如何将可观察到的RxJS中的异步数据发送到angular的下拉列表中?

[英]How to send asynchronous data in an RxJS Observable to a dropdown in angular?

I am trying to bring data( strings) sent from a rest API to a dropdown menu on an online form. 我试图将从rest API发送的数据(字符串)带到在线表单的下拉菜单中。 I cannot figure out where I am going wrong in my code, as it used to work, but now I am getting null / empty arrays coming in. 我无法弄清楚我的代码在哪里出了错,因为它可以正常工作,但是现在我收到了空/空数组。

I've tried switching around a lot of the array names, and trying to match things up, but I can't seem to make sense of things. 我尝试过切换很多数组名称,并试图将它们匹配起来,但是我似乎对这些事情没有任何意义。 I feel like I need to have my original array of strings that is filled with the subscribe method mentioned again, but I am not certain. 我觉得我需要将原始的字符串数组填充为再次提到的subscription方法,但是我不确定。

Variable/Method explanations: 变量/方法说明:

nameService : instance of name-service.ts. nameService :name-service.ts的实例。 this brings in the Observable array of strings from the api. 这从api中引入了Observable字符串数组。

names : a string array initialized empty, to be filled with the retrieved names names :初始化为空的字符串数组,将其填充为检索到的名称

nameSearch : the formControl Name for the element that contains the filtered search in the html and can be referenced in the .ts. nameSearch :formControl的元素的名称,该元素包含html中经过过滤的搜索,并且可以在.ts中引用。

filteredNames : an observable string array to be sent to the html object full of the names. filteredNames :一个可观察的字符串数组,将发送给充满名称的html对象。 not sure if I can bypass going through so many arrays, but my code is based off the angular Mat-Autocomplete filtered search template found here 不知道我是否可以绕过这么多数组,但是我的代码基于此处找到的角度Mat-Autocomplete过滤搜索模板

names() : getter method in the nameService. names() :nameService中的getter方法。 does not take params. 不带参数。

//In the NgOnInit:

this.nameService.names().subscribe(res => this.names= res).add( () => {
      console.log(this.names); //last place data is not null

      this.filteredNames = this.NameSearch.valueChanges.pipe(
        startWith(''),
        map(value => this._filter(value))
      )
      }
    )
//Outside NgOnInit custom _filter method, if this helps:

private _filter(value: string): string[] {
    console.log(value);
    const filterVal = value.toLowerCase();
    console.log(filterVal);
    let result = this.opts.filter(opt =>
      opt.toLowerCase().includes(filterVal)
    )
  }
//in the HTML:
    <mat-card class="item">
                    <label> Name:
            <br>
            <mat-form-field hintLabel="Pick your name or enter a new one">
              <input type="text" matInput formControlName="nameSearch" [matAutocomplete]="auto" required>
              <mat-autocomplete #auto="matAutocomplete">
                <mat-option *ngFor="let name of filteredNames | async" [value]="name">
                  {{ name }}
                </mat-option>
              </mat-autocomplete>
            </mat-form-field>
          </label>
                </mat-card>

I want the dropdown to have the list of names pulled in from the database displayed, but right now nothing is coming through. 我希望下拉列表显示从数据库中提取的名称列表,但是现在没有任何结果。 In my error tracing thusfar, I have found that the loss of data happens in the NgOnInit method, where I have commented in the code. 到目前为止,在我的错误跟踪中,我发现数据丢失发生在NgOnInit方法中,我在代码中对此进行了注释。 I have tried putting the this.names object in the pipe function to no avail. 我试着将this.names对象放在管道函数中无济于事。

I updated this according to your response. 我根据您的回复对此进行了更新。 Does this work? 这样行吗? Also I noticed that you have <label> including the whole input field, is that correct? 我还注意到您有<label>包括整个输入字段,对吗?

//In the NgOnInit:

this.names$ = this.nameService.names();
this.nameSearch$ = this.NameSearch.valueChanges(pipe(startWith('')));

this.filteredNames$ = combinelatest(this.names$, nameSearch$).pipe(
  (names, search)=> names.filter(name=>name.toLowerCase().includes(search.toLowerCase()))
  );


//in the HTML:
<mat-card class="item">
  <label> Name:</label>
  <br>
  <mat-form-field hintLabel="Pick your name or enter a new one">
    <input type="text" matInput formControlName="nameSearch" [matAutocomplete]="auto" required>

    <mat-autocomplete #auto="matAutocomplete">
      <mat-option *ngFor="let name of filteredNames$ | async" [value]="name">
        {{ name }}
      </mat-option>
    </mat-autocomplete>
  </mat-form-field>
</mat-card>

Your <mat-option> doesn't know what [value]="name" is. 您的<mat-option>不知道什么是[value]="name" Can you wrap the <mat-option> in a <div> and put the *ngFor on that? 您可以将<mat-option>包裹在<div> ,并在*ngFor放置*ngFor吗?

Also, if you do an async pipe on the ngFor you shouldn't need to do another one internally. 另外,如果您在ngFor上执行了异步管道操作,则无需在内部执行另一项操作。

<div *ngFor="let name of filteredNames | async">
  <mat-option [value]="name">
    {{ name }}
  </mat-option>
</div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM