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

Angular项目修改代码刷新页面后,数据获取失效如何解决?

问题解决:选择客户后刷新页面数据无法正常获取

问题描述

实现了客户选择功能:用户选择客户时,将客户ID保存到localStorage,同时通过服务同步状态。但修改代码并刷新页面后,无法正常获取数据,选中状态也异常。相关代码如下:

组件代码

export class AdminDashboardComponent implements OnInit{

  
  widgets = [1, 2, 3, 4];
  customers: Customer[] = [];
  selectedCustomerId!: string | null;

  constructor(private authService: AuthenticationService, private dbService: DbService, private customerSelectionService: CustomerSelectionService) { }

  
  ngOnInit() {

    this.selectedCustomerId = localStorage.getItem('selectedCustomerId');

    if (this.selectedCustomerId) {
      this.customerSelectionService.setSelectedCustomerId(this.selectedCustomerId);
    }

    this.fetchCustomers();
  }

  fetchCustomers() {
    this.dbService.selectCustomer().subscribe({
      next: (data: Customer[]) => {
        console.log(data);
        this.customers = data;
      },
      error: (error) => {
        console.error('Error fetching customers', error);
      },
      complete: () => console.log('Customer fetch completed')      
    });
  }

  onCustomerSelected(event: any) {
   
    const customerId = event.value;
    
    if (customerId !== null && customerId !== undefined) {
     
      this.selectedCustomerId = customerId;
      localStorage.setItem('selectedCustomerId', customerId.toString());
      this.customerSelectionService.setSelectedCustomerId(customerId.toString());
  
      this.dbService.sendCustomerId(customerId).subscribe({
        next: (response) => {
          localStorage.setItem('token', response.token);
          console.log('Customer ID sent to backend successfully:', response);
        },
        error: (error) => {
          console.error('Error sending customer ID to backend:', error);
        }
      });
    } else {
      console.error('Selected customer ID is null or undefined');
    }
  }
  
  

  logout() {
    this.authService.logout();
    
  }

}

选择功能HTML代码

<div class="selector">
        <mat-form-field>
          <mat-label>Select Customer</mat-label>
          <mat-select [value]="selectedCustomerId" (selectionChange)="onCustomerSelected($event)">
            <mat-option *ngFor="let customer of customers" [value]="customer.customer_id">
              {{ customer.customer_name }}
            </mat-option>
          </mat-select>
        </mat-form-field>
      </div>

客户选择服务代码

export class CustomerSelectionService {
  private selectedCustomerIdSource = new BehaviorSubject<string | null>(null);
  selectedCustomerId$ = this.selectedCustomerIdSource.asObservable();

  setSelectedCustomerId(customerId: string | null) {
    this.selectedCustomerIdSource.next(customerId);
  }

  
}

后端服务代码

selectCustomer(): Observable<any[]> {
    const httpOptions = {
      headers: new HttpHeaders({
        'Authorization': 'Bearer ' + localStorage.getItem('token')
      })
    };
    return this.http.get<any[]>(this.apiUrl + "/admin-dashboard", httpOptions);
  }

原因分析

  1. 类型不匹配:localStorage存储的是字符串类型,但customer.customer_id可能是数字类型,导致mat-select无法匹配选中项,视觉上显示未选中,进而影响后续数据逻辑。
  2. 初始化顺序问题:selectedCustomerId在客户列表加载前就已设置,但此时customers数组为空,mat-select无选项可匹配;客户列表加载完成后,Angular未自动触发变更检测更新选中状态。
  3. Token 有效性问题:刷新页面时,selectCustomer接口使用的是页面加载时的旧Token,若该Token未关联所选客户,会导致后端返回的客户列表异常或权限验证失败。

解决方案

1. 统一数据类型,确保选中值匹配

根据customer.customer_id的实际类型,统一selectedCustomerId的类型:

  • 若customer.customer_id为数字类型:
    // ngOnInit中
    const storedId = localStorage.getItem('selectedCustomerId');
    this.selectedCustomerId = storedId ? Number(storedId) : null;
    
    // onCustomerSelected中
    localStorage.setItem('selectedCustomerId', customerId.toString());
    this.selectedCustomerId = typeof customerId === 'string' ? Number(customerId) : customerId;
    
  • 若customer.customer_id为字符串类型,确保存储和读取一致:
    // fetchCustomers回调中转换类型(若后端返回数字)
    this.customers = data.map(cust => ({...cust, customer_id: cust.customer_id.toString()}));
    

2. 客户列表加载完成后同步选中状态

修改fetchCustomers,在客户列表加载完成后重新设置选中值,确保mat-select能正确匹配:

fetchCustomers() {
  this.dbService.selectCustomer().subscribe({
    next: (data: Customer[]) => {
      this.customers = data;
      // 列表加载完成后读取localStorage并设置选中值
      const storedId = localStorage.getItem('selectedCustomerId');
      if (storedId) {
        // 处理类型匹配
        this.selectedCustomerId = typeof this.customers[0]?.customer_id === 'number' ? Number(storedId) : storedId;
        this.customerSelectionService.setSelectedCustomerId(this.selectedCustomerId);
      }
    },
    error: (error) => {
      console.error('Error fetching customers', error);
    },
    complete: () => console.log('Customer fetch completed')      
  });
}

同时调整ngOnInit顺序,先加载客户列表再处理选中逻辑:

ngOnInit() {
  this.fetchCustomers();
}

3. 确保Token与所选客户关联有效

刷新页面时,先刷新关联所选客户的Token,再加载客户列表:

ngOnInit() {
  const storedId = localStorage.getItem('selectedCustomerId');
  if (storedId) {
    // 先刷新Token,确保权限正确
    this.dbService.sendCustomerId(storedId).subscribe({
      next: (response) => {
        localStorage.setItem('token', response.token);
        this.selectedCustomerId = storedId;
        this.customerSelectionService.setSelectedCustomerId(storedId);
        this.fetchCustomers();
      },
      error: (error) => {
        console.error('Error refreshing customer token:', error);
        localStorage.removeItem('selectedCustomerId');
        this.fetchCustomers();
      }
    });
  } else {
    this.fetchCustomers();
  }
}

4. 优化服务初始化逻辑

修改CustomerSelectionService,初始化时直接读取localStorage,减少组件手动同步代码:

export class CustomerSelectionService {
  private selectedCustomerIdSource = new BehaviorSubject<string | null>(
    localStorage.getItem('selectedCustomerId')
  );
  selectedCustomerId$ = this.selectedCustomerIdSource.asObservable();

  setSelectedCustomerId(customerId: string | null) {
    this.selectedCustomerIdSource.next(customerId);
    customerId ? localStorage.setItem('selectedCustomerId', customerId) : localStorage.removeItem('selectedCustomerId');
  }
}

组件中直接订阅服务的Observable更新视图:

ngOnInit() {
  this.customerSelectionService.selectedCustomerId$.subscribe(id => {
    this.selectedCustomerId = id;
  });
  // 其他初始化逻辑...
}

内容的提问来源于stack exchange,提问作者mbakgor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 02:19:58