代码之家  ›  专栏  ›  技术社区  ›  6324

类型Observable<Observable<any[]>>不可分配给类型Observable<any[]>

  •  5
  • 6324  · 技术社区  · 7 年前

    我正在使用数据库服务中的数据实现自动完成:

    @Injectable()
    export class SchoolService {
      constructor(private db: AngularFirestore) {
      }
    
      getSchools(): Observable<School[]> {
        return this.db.collection<School>('schools').valueChanges();
      }
    }
    

    在我的组件中:

    export class SchoolComponent implements OnInit {
      formControl: FormControl = new FormControl();
      schools: Observable<School[]>;
      filteredSchools: Observable<School[]>;
    
      constructor(private schoolService: SchoolService) {
      }
    
      ngOnInit() {
        this.schools = this.schoolService.getSchools();
    
        //Below line gives error "Type Observable<Observable<School[]>> is not assignable to type Observable<School[]>".
        this.filteredSchools = this.formControl.valueChanges.pipe(
          startWith(''),
          map(name => this.filterSchools(name))
        );
      }
    
      filterSchools(name: string): Observable<School[]> {
        return this.schools.map(school => school.filter(s => s.name.toLowerCase().includes(name)));
      }
    }
    

    和我的html:

    <form>
      <mat-form-field>
        <input type="text" matInput placeholder="Type Your School to Continue" [matAutocomplete]="auto"
               [formControl]="formControl">
        <mat-autocomplete #auto="matAutocomplete">
          <mat-option *ngFor="let school of filteredSchools | async" [value]="school">
            <span>{{school.name}}</span> |
            <small>{{school.city}}</small>
          </mat-option>
        </mat-autocomplete>
      </mat-form-field>
    </form>
    

    中的函数 ngOnInit 给予 Type Observable<Observable<School[]>> is not assignable to type Observable<School[]> 错误我怎样才能解决这个问题?

    2 回复  |  直到 7 年前
        1
  •  14
  •   martin    7 年前

    错误正好说明了问题所在。您定义了:

    filteredSchools: Observable<School[]>;
    

    但稍后您将创建一个Observable,它将发出(映射每个值)的结果 filterSchools(name: string): Observable<School[]> 它还返回一个可观察的,所以在最后你有一个可观察的 Observable<Observable<School[]>>

    看起来你只是想 switchMap (或 mergeMap concatMap )而不是 map 开关映射 将订阅嵌套的Observable并将链转换为 Observable<School[]> :

    this.filteredSchools = this.formControl.valueChanges.pipe(
      startWith(''),
      switchMap(name => this.filterSchools(name))
    );
    
        2
  •  0
  •   alsami    7 年前

    我建议使用 Observable.combineLatest(...)

    public ngOnInit(): void {
       this.schools = this.schoolService.getSchools();
    
       this.filteredSchools = Observable.combineLatest(
          this.formControl.valueChanges.startWith(''),
          this.schools
       ).map(([filter, schools]) => {
           if (!filter || filter === '') {
              return schools;
           }
    
           return schools.filter(s => s.name.toLowerCase().includes(name));
       });
    }
    

    只有当其中一个可观测对象发出新数据时,才会触发末尾仍有冷可观测对象。

    不是你的问题,但对于你的模板自动完成,你需要 displayWith 作用