带有异步集合的 ngb-pagination 不起作用
ngb-pagination with an async collection not working
我有以下 table 分页:
<ng-container mCardBody>
<fieldset class="form-group position-relative mb-0">
<input type="text" class="form-control form-control-xl input-xl" id="iconLeft1"
placeholder="Search Users" [formControl]="searchCtrl">
<div class="form-control-position">
<i class="feather ft-search font-medium-4"></i>
</div>
</fieldset>
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Lastname</th>
<th scope="col">Email</th>
<th scope="col" class="text-center">Admin</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let user of filteredUsers | async | slice: (page-1) * pageSize : page * pageSize; index as i">
<th scope="row">{{ user.id }}</th>
<td>{{ user.name }} </td>
<td>{{ user.lastname }}</td>
<td>{{ user.email }}</td>
<td class="text-center">
<i *ngIf="user.admin" style="color: green;" class="ficon feather ft-check"></i>
<i *ngIf="!user.admin" style="color: red;" class="ficon feather ft-x"></i>
</td>
<td>
<div ngbDropdown class="d-inline-block text-center">
<button class="btn btn-info" id="dropdownBasic1" ngbDropdownToggle>Action</button>
<div ngbDropdownMenu class="arrow _dropdown_mob dropdown-menu-right" aria-labelledby="dropdownBasic1">
<button class="dropdown-item" (click)="editUser(user)">Edit</button>
<button class="dropdown-item" (click)="deleteUser(user)">Delete</button>
</div>
</div>
</td>
</tr>
</tbody>
</table>
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center pagination-separate ">
<ngb-pagination [(page)]="page"
[pageSize]="pageSize"
[collectionSize]="filteredUsers.length" aria-label="Default pagination"></ngb-pagination>
</ul>
</nav>
</ng-container>
这是 ts
文件:
import { Component, OnInit } from '@angular/core';
import { DataService } from '../../_services/data.service'
import { NgBlockUI, BlockUI } from 'ng-block-ui'
import { AlertService } from '../../_services/alert.service'
import { ReactiveFormsModule, FormBuilder, FormControl, FormControlDirective, FormControlName, FormGroup, AbstractControl, Validators } from '@angular/forms';
import { Subject } from 'rxjs';
import { ReplaySubject } from 'rxjs';
import { take, takeUntil } from 'rxjs/operators';
@Component({
selector: 'app-users',
templateUrl: './users.component.html',
styleUrls: ['./users.component.css']
})
export class UsersComponent implements OnInit {
@BlockUI('changelog') blockUIChangelog: NgBlockUI;
users = [];
public breadcrumb: any;
options = {
close: false,
expand: true,
minimize: true,
reload: true
};
pageSize = 5;
page = 1;
public searchCtrl: FormControl = new FormControl();
private _onDestroy = new Subject<void>();
public filteredUsers: ReplaySubject<any[]> = new ReplaySubject<any[]>(1);
constructor(
private dataService: DataService,
private alertService: AlertService
) { }
ngOnInit(): void {
this.breadcrumb = {
'mainlabel': 'Users Administration',
'links': [
{
'name': 'Home',
'isLink': true,
'link': '/dashboard/sales'
},
{
'name': 'Admin Users',
'isLink': false,
'link': '#'
},
]
};
console.log('OnInit users component');
this.getUsers();
this.searchCtrl.valueChanges.pipe(takeUntil(this._onDestroy))
.subscribe(() => {
this.search();
});
}
ngOnDestroy() {
this._onDestroy.next();
this._onDestroy.complete();
}
search(){
console.log("Search invoked");
let search = this.searchCtrl.value;
console.log("Search term is:",search);
if (!search) {
console.log("Search is empty");
console.log("Filtered media is:",this.filteredUsers);
this.filteredUsers.next(this.users.slice());
return;
} else {
console.log("Filtered media is:",this.filteredUsers);
console.log("Search is:",search);
search = search.toLowerCase();
}
this.filteredUsers.next(
this.users.filter(user => (
user.name.toLowerCase().indexOf(search) > -1 ||
user.lastname.toLowerCase().indexOf(search) > -1
)
)
);
}
getUsers() {
this.dataService.getUsers().subscribe({
next: (users) => {
console.log('Received users:', users);
this.users = users;
this.filteredUsers.next(this.users);
},
error: (error) => {
console.log('Received error downloading users:', error);
}
})
}
editUser(user) {
console.log("Received user to edit:", user);
}
deleteUser(user) {
if (window.confirm('Sei sicuro di voler cancellare l\'utente?')) {
console.log("Received user to delete:", user);
var id = user.id;
this.blockUIChangelog.start('Loading..');
this.dataService.deleteUser(id)
.subscribe({
next: (response) => {
this.deleteRow(id);
this.alertService.success("User successfully deleted");
this.blockUIChangelog.stop();
},
error: (error) => {
this.alertService.error("An error occured");
this.blockUIChangelog.stop();
}
});
}
}
reloadChangelog() {
this.blockUIChangelog.start('Loading..');
this.getUsers();
setTimeout(() => {
this.blockUIChangelog.stop();
}, 2500);
}
deleteRow(id) {
for (let i = 0; i < this.users.length; ++i) {
if (this.users[i].id === id) {
this.users.splice(i, 1);
}
}
}
onUserCreated(user: any) {
console.log('OnUserCreated emitted:', user);
}
}
分页未显示任何页面,因为 filteredUsers
不是集合且无法检测大小。在这种情况下如何指示集合大小?考虑到它可以根据搜索而改变?
您可以应用 | async
管道来获得如下长度:
[collectionSize]="(filteredUsers | async)?.length"
我有以下 table 分页:
<ng-container mCardBody>
<fieldset class="form-group position-relative mb-0">
<input type="text" class="form-control form-control-xl input-xl" id="iconLeft1"
placeholder="Search Users" [formControl]="searchCtrl">
<div class="form-control-position">
<i class="feather ft-search font-medium-4"></i>
</div>
</fieldset>
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Lastname</th>
<th scope="col">Email</th>
<th scope="col" class="text-center">Admin</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let user of filteredUsers | async | slice: (page-1) * pageSize : page * pageSize; index as i">
<th scope="row">{{ user.id }}</th>
<td>{{ user.name }} </td>
<td>{{ user.lastname }}</td>
<td>{{ user.email }}</td>
<td class="text-center">
<i *ngIf="user.admin" style="color: green;" class="ficon feather ft-check"></i>
<i *ngIf="!user.admin" style="color: red;" class="ficon feather ft-x"></i>
</td>
<td>
<div ngbDropdown class="d-inline-block text-center">
<button class="btn btn-info" id="dropdownBasic1" ngbDropdownToggle>Action</button>
<div ngbDropdownMenu class="arrow _dropdown_mob dropdown-menu-right" aria-labelledby="dropdownBasic1">
<button class="dropdown-item" (click)="editUser(user)">Edit</button>
<button class="dropdown-item" (click)="deleteUser(user)">Delete</button>
</div>
</div>
</td>
</tr>
</tbody>
</table>
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center pagination-separate ">
<ngb-pagination [(page)]="page"
[pageSize]="pageSize"
[collectionSize]="filteredUsers.length" aria-label="Default pagination"></ngb-pagination>
</ul>
</nav>
</ng-container>
这是 ts
文件:
import { Component, OnInit } from '@angular/core';
import { DataService } from '../../_services/data.service'
import { NgBlockUI, BlockUI } from 'ng-block-ui'
import { AlertService } from '../../_services/alert.service'
import { ReactiveFormsModule, FormBuilder, FormControl, FormControlDirective, FormControlName, FormGroup, AbstractControl, Validators } from '@angular/forms';
import { Subject } from 'rxjs';
import { ReplaySubject } from 'rxjs';
import { take, takeUntil } from 'rxjs/operators';
@Component({
selector: 'app-users',
templateUrl: './users.component.html',
styleUrls: ['./users.component.css']
})
export class UsersComponent implements OnInit {
@BlockUI('changelog') blockUIChangelog: NgBlockUI;
users = [];
public breadcrumb: any;
options = {
close: false,
expand: true,
minimize: true,
reload: true
};
pageSize = 5;
page = 1;
public searchCtrl: FormControl = new FormControl();
private _onDestroy = new Subject<void>();
public filteredUsers: ReplaySubject<any[]> = new ReplaySubject<any[]>(1);
constructor(
private dataService: DataService,
private alertService: AlertService
) { }
ngOnInit(): void {
this.breadcrumb = {
'mainlabel': 'Users Administration',
'links': [
{
'name': 'Home',
'isLink': true,
'link': '/dashboard/sales'
},
{
'name': 'Admin Users',
'isLink': false,
'link': '#'
},
]
};
console.log('OnInit users component');
this.getUsers();
this.searchCtrl.valueChanges.pipe(takeUntil(this._onDestroy))
.subscribe(() => {
this.search();
});
}
ngOnDestroy() {
this._onDestroy.next();
this._onDestroy.complete();
}
search(){
console.log("Search invoked");
let search = this.searchCtrl.value;
console.log("Search term is:",search);
if (!search) {
console.log("Search is empty");
console.log("Filtered media is:",this.filteredUsers);
this.filteredUsers.next(this.users.slice());
return;
} else {
console.log("Filtered media is:",this.filteredUsers);
console.log("Search is:",search);
search = search.toLowerCase();
}
this.filteredUsers.next(
this.users.filter(user => (
user.name.toLowerCase().indexOf(search) > -1 ||
user.lastname.toLowerCase().indexOf(search) > -1
)
)
);
}
getUsers() {
this.dataService.getUsers().subscribe({
next: (users) => {
console.log('Received users:', users);
this.users = users;
this.filteredUsers.next(this.users);
},
error: (error) => {
console.log('Received error downloading users:', error);
}
})
}
editUser(user) {
console.log("Received user to edit:", user);
}
deleteUser(user) {
if (window.confirm('Sei sicuro di voler cancellare l\'utente?')) {
console.log("Received user to delete:", user);
var id = user.id;
this.blockUIChangelog.start('Loading..');
this.dataService.deleteUser(id)
.subscribe({
next: (response) => {
this.deleteRow(id);
this.alertService.success("User successfully deleted");
this.blockUIChangelog.stop();
},
error: (error) => {
this.alertService.error("An error occured");
this.blockUIChangelog.stop();
}
});
}
}
reloadChangelog() {
this.blockUIChangelog.start('Loading..');
this.getUsers();
setTimeout(() => {
this.blockUIChangelog.stop();
}, 2500);
}
deleteRow(id) {
for (let i = 0; i < this.users.length; ++i) {
if (this.users[i].id === id) {
this.users.splice(i, 1);
}
}
}
onUserCreated(user: any) {
console.log('OnUserCreated emitted:', user);
}
}
分页未显示任何页面,因为 filteredUsers
不是集合且无法检测大小。在这种情况下如何指示集合大小?考虑到它可以根据搜索而改变?
您可以应用 | async
管道来获得如下长度:
[collectionSize]="(filteredUsers | async)?.length"