我试图在一个带有分页器的mat表上创建一个搜索,当组件加载的功能与预期相同时,当我单击下一个页面并在开发人员工具中查看网络时,我会看到一个请求和一个响应,当我现在搜索它仍然发出一个请求和一个响应时,但是当我在下一页搜索时,我看到它发出了两个请求,得到了两个响应,所以它是重复的;如果我再次搜索,它在下一个页面之后发出3个请求和响应,等等,然后我再次单击下一个页面,但是每次搜索仍然只有一个请求和响应。
想知道是否有人能在这个问题上引导我做正确的事。
这是我的组件
import {Component, OnInit, ViewChild} from '@angular/core';
import {MatDialogRef,MatDialog} from '@angular/material'
import {MatPaginator, MatSort} from '@angular/material';
import {merge, Observable, of as observableOf} from 'rxjs';
import {catchError, map, startWith, switchMap} from 'rxjs/operators';
import {DataService} from '@app/providers'
import {UserAdd} from '@app/modules/features/admininstration/pages/users/modals/user_add/user_add'
import {UserEdit} from '@app/modules/features/admininstration/pages/users/modals/user_edit/user_edit'
import {UserOtp} from '@app/modules/features/admininstration/pages/users/modals/user_otp/user_otp'
import * as u from '@app/models/user'
/**
* @title Table retrieving data through HTTP
*/
@Component({
selector: 'users',
styleUrls: ['users.scss'],
templateUrl: 'users.html',
})
export class Users implements OnInit {
displayedColumns: string[] = ['username', 'firstname', 'surname','userrole','usertype', 'created','actions'];
data: u.UserGrid[] = []
search: string = "";
resultsLength = 0;
isLoadingResults = true;
isRateLimitReached = false;
userAdd: MatDialogRef<UserAdd>;
userEdit: MatDialogRef<UserEdit>;
userOtp: MatDialogRef<UserOtp>;
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
constructor(private ds:DataService,private dialog:MatDialog) {}
ngOnInit() {
// If the user changes the sort order, reset back to the first page.
this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0);
this.sort.direction = 'asc';
this.sort.active = 'firstname';
this.loadGridData();
}
loadGridData(){
merge(this.sort.sortChange, this.paginator.page)
.pipe(
startWith({}),
switchMap(() => {
this.isLoadingResults = true;
return this.ds!.getUsers(this.search,this.sort.active+'_'+this.sort.direction,10,this.paginator.pageIndex);
}),
map(data => {
// Flip flag to show that loading has finished.
this.isLoadingResults = false;
this.isRateLimitReached = false;
this.resultsLength = data.count;
return data.users;
}),
catchError(() => {
this.isLoadingResults = false;
this.isRateLimitReached = true;
return observableOf([]);
})
).subscribe(data => this.data = data);
}
userSearch(){
this.paginator.pageIndex = 0;
this.loadGridData();
}
openUserAdd(){
this.userAdd = this.dialog.open(UserAdd,{
disableClose: false,
width: '550px',
height: '50%',
})
}
openUserEdit(id:string){
this.userEdit = this.dialog.open(UserEdit,{
disableClose: false,
width: '550px',
height: '50%',
})
this.userEdit.componentInstance.id = id;
}
openUserOtp(){
this.userOtp = this.dialog.open(UserOtp,{
disableClose: false,
width: '500px',
height: '150px'
})
}
deleteUser(id:string){
this.ds.deleteUser(id).subscribe(()=>{
this.loadGridData();
});
}
}这是我的模板。
<mat-toolbar color="accent" class="mini-toolbar" fxLayout="row" fxLayoutAlign="space-between center">
<span>Users</span>
<div fxLayout="row">
<mat-form-field class="full-width" fxLayoutAlign="center center">
<input placeholder="What are you looking for?" matInput [(ngModel)]="search" (keyup.enter)="userSearch()">
</mat-form-field>
<div fxFlex="10px"></div>
<div class="custom_button" style="margin-top: 13px; width: 100px" fxLayoutAlign="center center" (keyup.enter)="userSearch()"
(click)="userSearch()">
SEARCH
</div>
<div fxFlex="10px"></div>
<div class="custom_button" style="margin-top: 13px;width: 150px" fxLayoutAlign="center center" (click)="openUserAdd()">
CREATE USER
</div>
</div>
</mat-toolbar>
<div class="example-loading-shade" *ngIf="isLoadingResults || isRateLimitReached">
<mat-spinner *ngIf="isLoadingResults"></mat-spinner>
<div class="example-rate-limit-reached" *ngIf="isRateLimitReached">
Error retrieving data.
</div>
</div>
<div fxLayout="row" class="sitegroup-container" fxLayoutAlign="start stretch">
<div fxFlex="100%" class="data_container">
<table mat-table [dataSource]="data" class="example-table" matSort matSortActive="firstname" matSortDisableClear matSortDirection="asc">
<!-- Username Column -->
<ng-container matColumnDef="username">
<th mat-header-cell *matHeaderCellDef>Username</th>
<td mat-cell *matCellDef="let row">{{row.username}}</td>
</ng-container>
<!-- Firstname Column -->
<ng-container matColumnDef="firstname">
<th mat-header-cell *matHeaderCellDef mat-sort-header disableClear>Firstname</th>
<td mat-cell *matCellDef="let row">{{row.firstname}}</td>
</ng-container>
<!-- Surname Column -->
<ng-container matColumnDef="surname">
<th mat-header-cell *matHeaderCellDef mat-sort-header disableClear>Surname</th>
<td mat-cell *matCellDef="let row">{{row.surname}}</td>
</ng-container>
<!-- UserROle Column -->
<ng-container matColumnDef="userrole">
<th mat-header-cell *matHeaderCellDef mat-sort-header disableClear>User Role</th>
<td mat-cell *matCellDef="let row">{{row.userRole}}</td>
</ng-container>
<!-- UserType Column -->
<ng-container matColumnDef="usertype">
<th mat-header-cell *matHeaderCellDef mat-sort-header disableClear>User Type</th>
<td mat-cell *matCellDef="let row">{{row.userType}}</td>
</ng-container>
<!-- Created Column -->
<ng-container matColumnDef="created">
<th mat-header-cell *matHeaderCellDef>
Created
</th>
<td mat-cell *matCellDef="let row">{{row.created | date}}</td>
</ng-container>
<!-- Actions Column-->
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef>
</th>
<td mat-cell *matCellDef="let row">
<div fxLayout="row" fxLayoutAlign="end">
<button matTooltip="OTP" [matTooltipPosition]="'left'" mat-icon-button (click)="openUserOtp()" color="accent">
<mat-icon>smartphone</mat-icon>
</button>
<button matTooltip="Edit" [matTooltipPosition]="'left'" mat-icon-button (click)="openUserEdit(row.id)" color="accent">
<mat-icon>create</mat-icon>
</button>
<button matTooltip="Delete" [matTooltipPosition]="'left'" mat-icon-button (click)="deleteUser(row.id)" color="accent">
<mat-icon>delete</mat-icon>
</button>
</div>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<mat-paginator [length]="resultsLength" [pageSize]="10"></mat-paginator>
</div>
</div>发布于 2018-10-17 11:44:09
我更改了我的userSearch函数,并添加了一个refreshGrid函数来获取用户和resultsLength,而不是调用loadGrid函数,这样我就不会继续添加更多的订阅。
userSearch(){
this.paginator.pageIndex = 0;
this.refreshGrid();
}
refreshGrid(){
this.isLoadingResults = true;
this.ds!.getUsers(this.search,this.sort.active+'_'+this.sort.direction,10,this.paginator.pageIndex).subscribe((data)=>{
this.resultsLength = data.count;
this.data = data.users;
this.isLoadingResults = false;
})
}发布于 2018-10-04 16:08:43
每次调用loadGridData()时,都会订阅在合并上可观察到的构建。在没有删除订阅的情况下,您在代码中执行了几次此操作。因此,添加或删除用户将创建一个全新的订阅,因为您再次调用loadGridData(),增加了您正在进行的http调用的数量(由于链上的更改,较旧的订阅将触发)。
您的数据加载方式有几个基本问题,我建议您重新评估这一点。
一些建议:
如果您使用异步,则角框架负责订阅外部可观测对象(来自主题的订阅)。
注-用下面的示例替换这里的一些评论
下面是一个简单的示例,希望这将显示一种方法来避免不断添加的调用。
app.component.html
<div>
<button (click)="loadData()">Refresh</button>
</div>
<div *ngIf="currentTime$ | async as currentTime">
<p>{{currentTime.currentFileTime}}</p>
</div>app.component.ts
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { map, take } from 'rxjs/operators';
import { Subject } from 'rxjs';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
public currentTime$ = new Subject<any>();
private httpClient: HttpClient;
constructor(http: HttpClient) {
this.httpClient = http;
}
public ngOnInit() {
this.loadData();
}
public loadData() {
const path = 'http://worldclockapi.com/api/json/est/now';
const subscription = this.httpClient.get<any>(path).pipe(take(1), map((val) => val)).subscribe(
(data) => {
this.currentTime$.next(data);
},
(error) => {
console.log(error);
},
() => {
if (subscription && !subscription.closed) {
subscription.unsubscribe();
}
});
}
}app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [ ],
bootstrap: [AppComponent]
})
export class AppModule { }因此,每当您按"Refresh“时,都会生成一个http调用,但是旧的订阅会在完成时关闭。“采取(1)”导致完成在第一次获得,从而使这种行为方式,我认为您希望您的数据流。
https://stackoverflow.com/questions/52636091
复制相似问题