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
我正在开发 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