首页 文章

来自2个不同Web服务的Angular Populate mat-optgroup / mat-options

提问于
浏览
0

我是Angular的新手,并尝试在我的Angualr 6应用程序中添加带选项组的mat-select . 我有一个包含2个URL的现有Web API . 一个URL返回Groups,另一个返回给定groupId的每个Group中的Items .

加载时,此页面进入无限循环 . 为了排除故障,我尝试在ngOnInit()中为this.groups添加一个 Logger ,这样我就可以构造HTML使用的数组,但看起来像.groups / this.items没有初始化,直到HTML页面调用 .

我必须接近这个错误 . 我只是尝试添加一个HTML mat-select,其中mat-optgroups由1 webservice确定/ mat-options由另一个webservice确定 .

我根据这个例子构建了这个例子(https://material.angular.io/components/select/overview#creating-groups-of-options):

navigation.component.ts

import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
import {HttpErrorResponse} from '@angular/common/http';
import {Component, OnInit} from '@angular/core';
import { Group } from '../group';
import { GroupService } from '../group.service';
import { Item } from '../item';
import { ItemService } from '../item.service';

@Component({
  selector: 'app-navigation',
  templateUrl: './navigation.component.html',
  styleUrls: ['./navigation.component.css']
})
export class NavigationComponent implements OnInit {

  groups: Group [] = [];
  items: Item [] = [];
  pokemonControl = new FormControl();


  constructor(private groupService: GroupService, private itemService: ItemService) {}


  ngOnInit () {
    this.getGroups();
    console.log("length: " + this.groups.length); // logs 0 as length
  }

  getGroups(): void {
    this.groupService.getGroups().subscribe(
      data => {
        this.groups = data as Group[];
        console.log(data);
      },
      (err: HttpErrorResponse) => {
        console.log (err.message);
      }
    );

  }

  getItems(department: number): void {
    this.itemService.getItems(department).subscribe(
      data => {
        this.items = data as Item[];
        console.log(data);
      },
      (err: HttpErrorResponse) => {
        console.log (err.message);
      }
    );
  }

}

group.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';

import { Observable, of } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';

import { Group } from './group';

@Injectable({
  providedIn: 'root'
})
export class GroupService {

  private groupsUrl = 'http://localhost:8180';

  constructor(private http: HttpClient) { }

   getGroups (): Observable<Group[]> {
    const url = `${this.groupsUrl}/groups`;
    return this.http.get<Group[]>(url);
  }

  private handleError<T> (operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {
    console.error(error);
    console.log(`${operation} failed: ${error.message}`);
    return of(result as T);
    };
  }

}

item.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';

import { Observable, of } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';

import { Item } from './item';

@Injectable({
  providedIn: 'root'
})
export class ItemService {

  private itemsUrl = 'http://localhost:8180';

  constructor(
    private http: HttpClient) { }


   getItems (groupId: number): Observable<Item[]> {
    const url = `${this.itemsUrl}/groups/${groupId}/items`;
    return this.http.get<Item[]>(url);
  }

  private handleError<T> (operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {
      console.error(error);
      console.log(`${operation} failed: ${error.message}`);
      return of(result as T);
    };
  }

}

HTML

<mat-select [formControl]="pokemonControl">
  <mat-optgroup *ngFor="let group of group.groupList" [label]="group.groupName"
                [disabled]="group.disabled">
    <mat-option *ngFor="let item of getItems(group.groupId).itemList" [value]="item.itemId">
      {{item.itemName}}
    </mat-option>
  </mat-optgroup>
</mat-select>

1 回答

  • 0

    检查这一行:

    let item of getItems(group.groupId).itemList
    

    该指令位于另一个 *ngFor 内,因此执行的时间与 group.groupList 的长度一样多 .

    如果它是10个元素长,则 getItems(...) 方法将被调用10次,并且每次它将产生HTTPRequest,并且在异步应答之后,它将覆盖 items 变量 .

    因此行为是不可预测的,并且 items 变量不可用,因为它在几秒钟内改变了几次 . 你说的体验就像一个无限循环,它可能只是变化检测,它响应新的变化产生一个新的变化 .

    解决方案:

    Don't subscribe several observables if you need to use them synchronously!

    Observable是异步的 . 您无法猜测它何时会执行订阅代码,即订单或 whenever .

    Rxjs为几个运营商提供了解决这个问题的方法 . 您可以检查组合运算符here .

相关问题