Angular 进行两次 http 调用

Angular makes http call twice

我正在开发 Angular 应用程序。 我有一个自定义数据源,它从服务器获取数据并填充 material table.

这是来自服务的方法:

dataChange: BehaviorSubject<Segment[]> = new BehaviorSubject<Segment[]>([]);

 getSegmentsByProgramId(programId: number) {
    this.subscription = this.httpClient
      .get<Segment[]>(`${environment.baseUrl}/segment/program/${programId}`)

      .subscribe(
        segments => {
          this.dataChange.next(segments);
        },
        (error: HttpErrorResponse) => {
          console.log(error.message);
        },
        () => console.log('completed')
      );
  }

这里是 parent 组件的模板:

<mat-card class="mat-elevation-z10 mt-2">
  <mat-card-header>
    <mat-card-title>
      <h4 class="card-title">Segments</h4>
    </mat-card-title>
  </mat-card-header>
  <mat-card-content class="mr-3">
    <mat-tab-group>
      <mat-tab *ngFor="let program of programs$ | async">
        <ng-template mat-tab-label>
          <span> {{ program.name }} </span></ng-template
        >
        <app-segment-table [programId]="program.id"></app-segment-table>
      </mat-tab>
    </mat-tab-group>
  </mat-card-content>
</mat-card>

这里是 parent 组件的.ts:

export class SegmentListComponent implements OnInit {
  programs$: Observable<Program[]>;
  members$: Observable<number>;

  @Output() createSegmentEvent = new EventEmitter();

  constructor(private programService: ProgramService, private membersService: MembersService) {}

  ngOnInit() {
    this.programs$ = this.programService.programs$;
    this.members$ = this.membersService.members$.pipe(map(members => members.length));
  }

  createSegment() {
    this.createSegmentEvent.next(true);
  }
}

在child中:

export class SegmentTableComponent implements OnInit {
  segmentsDatabase: SegmentsService | null;
  dataSource: SegmentsDataSource | null;
  displayedColumns = ['name', 'startDate', 'endDate', 'cashback', 'strategy', 'status', 'members', 'actions'];
  index: number;
  id: number;

  isLoading = true;

  @Input() programId: number | any;

  @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator;
  @ViewChild(MatSort, { static: true }) sort: MatSort;
  @ViewChild('filter', { static: true }) filter: ElementRef;

  constructor(public httpClient: HttpClient, private segmentsService: SegmentsService, public dialog: MatDialog) {}

  ngOnInit() {
    this.loadData(this.programId);
  }

  public loadData(programId: number | any) {
    this.segmentsDatabase = new SegmentsService(this.httpClient);
    this.dataSource = new SegmentsDataSource(this.segmentsDatabase, this.paginator, this.sort, programId);

    fromEvent(this.filter.nativeElement, 'keyup')
      .pipe(debounceTime(150), distinctUntilChanged())
      .subscribe(() => {
        if (!this.dataSource) {
          return;
        }
        this.dataSource.filter = this.filter.nativeElement.value;
      });
  }
}

这是数据源:

export class SegmentsDataSource extends DataSource<Segment> {
  _filterChange = new BehaviorSubject('');

  get filter(): string {
    return this._filterChange.value;
  }

  set filter(filter: string) {
    this._filterChange.next(filter);
  }

  filteredData: Segment[] = [];
  renderedData: Segment[] = [];

  constructor(
    public _segmentsDataBase: SegmentsService,
    public _paginator: MatPaginator,
    public _sort: MatSort,
    public _programId: number | any
  ) {
    super();
    this._filterChange.subscribe(() => (this._paginator.pageIndex = 0));
  }

  connect(): Observable<Segment[]> {
    const displayDataChanges = [
      this._segmentsDataBase.dataChange,
      this._sort.sortChange,
      this._filterChange,
      this._paginator.page,
      this._programId
    ];

    this._segmentsDataBase.getSegmentsByProgramId(this._programId);

    return merge(...displayDataChanges).pipe(
      map(() => {
        this.filteredData = this._segmentsDataBase.data.slice().filter((segment: Segment) => {
          const searchStr = (
            segment.name +
            segment.startDate +
            segment.endDate +
            segment.cashback +
            segment.status
          ).toLowerCase();
          return searchStr.indexOf(this.filter.toLowerCase()) !== -1;
        });
        const sortedData = this.sortData(this.filteredData.slice());

        const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
        this.renderedData = sortedData.splice(startIndex, this._paginator.pageSize);
        return this.renderedData;
      })
    );
  }

  disconnect() {}
}

当我访问此页面并重新加载它时 - 一切正常。服务被调用一次。 但是当我从另一个页面传输时......我的服务器被调用了两次。

我不知道是什么导致了这个问题... 也许有人可以帮我解决。

最好在 this.httpClient 请求中使用管道来获取异步结果。事件。当您转移到另一个站点时,您 运行 处于错误情况,angular 的重试选项将重试该请求。

例如:

getHero(id: number): Observable<Hero> {
  const url = `${this.heroesUrl}/${id}`;
  return this.http.get<Hero>(url).pipe(
    tap(_ => this.log(`fetched hero id=${id}`)),
    catchError(this.handleError<Hero>(`getHero id=${id}`))
  );
}

这是一个ref