带有异步集合的 ngb 分页不起作用

问题描述

我有以下带分页的表格:

 <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"

Sample solution on StackBlitz

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...