You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 18客户列表组件本地存储分页状态自动重置为1的问题排查求助

Angular 18客户列表组件本地存储分页状态自动重置为1的问题排查求助

问题描述

我正在开发一个Angular 18客户列表组件,要求将筛选器状态和当前页码保存到localStorage中,这样用户跳转到其他页面后再返回列表时,能恢复到之前的状态。但现在遇到了一个问题:当我选择分页中的某一页,跳转到其他页面后再返回列表,分页会自动重置为1。我跟踪后发现,组件初始化时确实从localStorage加载了状态,但之后又变回了1。我已经创建了一个服务来处理数据获取和本地存储操作,想找出这个问题的原因,考虑过把状态加载逻辑放到构造函数里,但还是觉得放在ngOnInit更合适。

组件代码

@Component({
  selector: 'app-cliente-list',
  standalone: true,
  imports: [NgbPaginationModule, ClienteFiltersComponent, NgForOf, NgIf, FaIconComponent],
  providers: [{ provide: ClienteGateway, useClass: ClienteApiService }, ListarClienteUseCase],
  templateUrl: './cliente-list.component.html',
  styleUrls: ['./cliente-list.component.scss']
})
export class ClienteListComponent implements OnInit {

  filtros: any = { nombre: '', tipo_cliente: '', tiene_credito: null };
  clientes: Cliente[] = [];
  count: number = 0;
  current_page: number = 1;

  constructor(
    private readonly listarClienteUseCase: ListarClienteUseCase,
    private readonly toastService: ToastService,
    private readonly modalService: NgbModal,
    private readonly breadcrumbService: BreadcrumbService,
    private readonly route: ActivatedRoute,
    private readonly router: Router,
    private readonly clienteStateService: ClienteStateService
  ) { }

  ngOnInit(): void {
    const { filtros, page } = this.clienteStateService.getState();
    this.filtros = filtros || this.filtros;
    this.current_page = page ?? 1;
    this.loadClientes(this.current_page, this.filtros);
    this.breadcrumbService.addBreadcrumb({
      label: 'Lista de Cliente',
      url: this.route.snapshot.url.join('/'),
      nivel: 2,
    });
  }

  loadClientes(page: number, filtros: any): void {
    this.listarClienteUseCase.execute(page, filtros).subscribe({
      next: (response) => {
        this.clientes = response.results;
        this.count = response.count;
        this.current_page = response.current_page;
        this.clienteStateService.saveState({ filtros: this.filtros, page: this.current_page });
      },
      error: (err) => {
        this.toastService.error('Error al cargar clientes:', err);
      },
    });
  }

  onPageChange(page: number): void {
    this.current_page = page;
    this.clienteStateService.saveState({ filtros: this.filtros, page: this.current_page });
    this.loadClientes(this.current_page, this.filtros);
  }

  verDetalle(clienteId: number): void {
    this.clienteStateService.saveState({ filtros: this.filtros, page: this.current_page });
    this.router.navigate(['/clientes', clienteId]);
  }

  trackByClienteId(index: number, cliente: Cliente): number {
    return cliente.id;
  }

  openFiltrosCliente(content: TemplateRef<any>) {
    const modalRef = this.modalService.open(content, { ariaLabelledBy: 'modal-basic-title', scrollable: true, size: 'lg' });
    modalRef.result.then((filtros: any) => {
      if (filtros) {
        this.filtros = filtros;
        this.current_page = 1;
        this.loadClientes(this.current_page, this.filtros);
      }
    }, (reason) => {
      console.log('Modal cerrado:', reason);
    });
  }
} 

状态服务代码

@Injectable({
  providedIn: 'root'
})
export class ClienteStateService {

  private readonly stateKey = 'clienteListState';

  constructor() { }

  saveState(state: { filtros: any; page: number }): void {
    localStorage.setItem(this.stateKey, JSON.stringify(state));
  }

  getState(): { filtros: any; page: number } {
    const storedState = localStorage.getItem(this.stateKey);
    if (storedState) {
      return JSON.parse(storedState);
    }
    return { filtros: { nombre: '', tipo_cliente: '', tiene_credito: null }, page: 1 };
  }

  clearState(): void {
    localStorage.removeItem(this.stateKey);
  }
}

问题排查与解决方案

仔细看你的代码,我发现了一个很可能导致问题的点:在loadClientes方法的next回调中,你将response.current_page赋值给了this.current_page,然后用这个值去更新本地存储。这就意味着如果后端接口返回的current_page始终是1(比如没有正确处理你传入的page参数),那么它会覆盖你从本地存储加载的正确页码。

验证步骤

  1. 在ngOnInit中加载完本地存储的页码后,添加console.log('加载的页码:', this.current_page),确认初始加载的页码是正确的。
  2. 在loadClientes的next回调中,添加console.log('后端返回的页码:', response.current_page),看看后端返回的是不是1。如果是,那问题就出在这里。

修改建议

你应该信任前端传入的page参数(不管是从本地存储加载的,还是用户点击分页选择的),而不是后端返回的current_page。修改loadClientes方法如下:

loadClientes(page: number, filtros: any): void {
  this.listarClienteUseCase.execute(page, filtros).subscribe({
    next: (response) => {
      this.clientes = response.results;
      this.count = response.count;
      // 改用传入的page参数,而不是后端返回的current_page
      this.current_page = page; 
      this.clienteStateService.saveState({ filtros: this.filtros, page: this.current_page });
    },
    error: (err) => {
      this.toastService.error('Error al cargar clientes:', err);
    },
  });
}

额外检查点

  • 确认ListarClienteUseCase和对应的API服务是否正确将page参数传递给后端,后端是否正确处理了分页参数并返回对应页的数据。
  • 可以在clienteStateService.saveState方法中添加console.log('保存的页码:', state.page),跟踪每次保存的页码是否正确,排查是否有其他地方意外将页码设为1。

备注:内容来源于stack exchange,提问作者Wilson Coronado

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 15:18:01