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

Angular中localStorage数据传递与下拉框预填异常问题排查

Angular localStorage 联动下拉框不更新问题

问题场景

在Angular项目中实现localStorage联动功能:首页有6个城市按钮,点击按钮时将对应城市名存入localStorage,同时跳转到用户输入组件;该组件的下拉框包含与首页相同的城市列表,需自动选中localStorage中保存的城市。例如点击东京按钮后,跳转至用户输入组件时,下拉框应默认选中东京,但目前点击任意按钮跳转后,下拉框始终保持默认值伦敦,未更新。

首页HTML代码

<div class="grid">
  <button *ngFor="let button of buttons" [value]="button.name" pButton type="button" routerLink="/weather-data" (click)="changeCityData($event)">
    {{button.name}}
  </button>
</div>

首页TS组件代码

export class HomeComponent implements OnInit {
  buttons: City[];
  constructor(
    private weatherService: WeatherService,
    private localService: LocalService
  ) {
    this.buttons = [
      new City('London', '51.51', '-0.13'),
      new City('Sydney', '-33.87', '151.21'),
      new City('New York', '40.71', '-74.01'),
      new City('Paris', '48.85', '2.35'),
      new City('Tokyo', '35.69', '139.69'),
      new City('Bratislava', '48.15', '17.11'),
    ];
  }
  ngOnInit(): void {}

  changeCityData(event) {
    const city = event.target.value;     // 此处将城市存入localStorage
    this.localService.saveData('city', city); // <=

    if (event.target.value === 'London') {
      this.weatherService.coordinatesSubject.next({
        lat: '51.51',
        lon: '-0.13',
        startDate: '2005-08-25',
      });
    } else if (event.target.value === 'New York') {
      this.weatherService.coordinatesSubject.next({
        lat: '40.71',
        lon: '-74.01',
        startDate: '2005-08-25',
      });
    } else if (event.target.value === 'Tokyo') { 
      // 其他城市逻辑...
    }
  }
}

用户输入组件HTML代码

<form class="user-input" [formGroup]="userInput" (ngSubmit)="onSubmit()">
  <p-dropdown [options]="cities" formControlName="selectedCity" optionLabel="name"></p-dropdown>
  <p> weather data for </p>
  <p-calendar placeholder="Choose a date" formControlName="selectedDate"></p-calendar>
  <button [disabled]="!userInput.controls['selectedDate'].value" style="margin-left: 10px;" class="form-control" pButton label="Submit"></button>
</form>

用户输入组件TS代码

export class UserInputComponent implements OnInit {
  cities: City[];
  value: Date;
  userInput: FormGroup;

  constructor(
    private weatherService: WeatherService,
    private router: Router,
    private datePipe: DatePipe,
    private localService: LocalService
  ) {
    this.cities = [
      new City('London', '51.51', '-0.13'),
      new City('Sydney', '-33.87', '151.21'),
      new City('New York', '40.71', '-74.01'),
      new City('Paris', '48.85', '2.35'),
      new City('Tokyo', '35.69', '139.69'),
      new City('Bratislava', '48.15', '17.11'),
    ];
  }

  ngOnInit(): void {
    this.userInput = new FormGroup({
      selectedCity: new FormControl(new City('London', '51.51', '-0.13')),  // 此处设置默认城市
      selectedDate: new FormControl(null),
    });
    
    this.userInput.controls['selectedCity'].setValue(     // 尝试设置下拉框选中localStorage中的城市
      this.localService.getData('city')
    );

    this.userInput.controls['selectedDate'].setValue(
      this.datePipe.transform(sessionStorage.getItem('date'), 'MM/dd/yyyy')
    );
  }


  onSubmit() {
    this.router
      .navigateByUrl('/', { skipLocationChange: true })
      .then(() => this.router.navigate(['/weather-data']));
    const lat = this.userInput.controls['selectedCity'].value.lat;
    const lon = this.userInput.controls['selectedCity'].value.lon;
    const startDate = this.datePipe.transform(
      this.userInput.controls['selectedDate'].value,
      'yyyy-MM-dd'
    );
    sessionStorage.setItem('date', startDate);
    this.localService.saveData(
      'city',
      this.userInput.controls['selectedCity'].value.name
    );
    this.weatherService.coordinatesSubject.next({
      lat: lat,
      lon: lon,
      startDate: startDate,
    });
  }
}

问题原因

  1. 数据类型不匹配:localStorage中存储的是城市名称字符串(如'Tokyo'),但下拉框的selectedCity控件绑定的是City对象。直接将字符串赋值给控件,下拉框无法匹配到对应的City选项,因此保持默认的伦敦。
  2. 路由跳转时序问题:按钮同时使用routerLink和(click),可能出现路由先完成跳转,而changeCityData还未完成localStorage存储的情况。

修复方案

1. 修正数据类型匹配问题

在用户输入组件的ngOnInit中,需要从cities数组中找到与localStorage存储的城市名对应的City对象,再赋值给控件:

ngOnInit(): void {
  // 获取localStorage中的城市名,做空值判断
  const savedCityName = this.localService.getData('city');
  // 匹配对应的City对象,默认选伦敦
  const targetCity = savedCityName 
    ? this.cities.find(city => city.name === savedCityName) 
    : new City('London', '51.51', '-0.13');

  this.userInput = new FormGroup({
    selectedCity: new FormControl(targetCity),
    selectedDate: new FormControl(null),
  });

  // 日期逻辑保持不变
  this.userInput.controls['selectedDate'].setValue(
    this.datePipe.transform(sessionStorage.getItem('date'), 'MM/dd/yyyy')
  );
}

2. 优化路由跳转逻辑

移除按钮上的routerLink,改为在changeCityData中手动触发路由跳转,确保localStorage存储完成后再跳转:

首页TS修改(注入Router并手动跳转)

export class HomeComponent implements OnInit {
  buttons: City[];
  constructor(
    private weatherService: WeatherService,
    private localService: LocalService,
    private router: Router // 注入Router
  ) {
    // 城市列表保持不变
    this.buttons = [
      new City('London', '51.51', '-0.13'),
      new City('Sydney', '-33.87', '151.21'),
      new City('New York', '40.71', '-74.01'),
      new City('Paris', '48.85', '2.35'),
      new City('Tokyo', '35.69', '139.69'),
      new City('Bratislava', '48.15', '17.11'),
    ];
  }
  ngOnInit(): void {}

  changeCityData(event) {
    const city = event.target.value;
    this.localService.saveData('city', city);

    // 优化城市坐标匹配逻辑,避免多个if else
    const targetCity = this.buttons.find(b => b.name === city);
    if (targetCity) {
      this.weatherService.coordinatesSubject.next({
        lat: targetCity.lat,
        lon: targetCity.lon,
        startDate: '2005-08-25',
      });
    }

    // 手动跳转路由
    this.router.navigate(['/weather-data']);
  }
}

首页HTML修改(移除routerLink)

<div class="grid">
  <button *ngFor="let button of buttons" [value]="button.name" pButton type="button" (click)="changeCityData($event)">
    {{button.name}}
  </button>
</div>

额外优化建议

  • 将城市列表抽成全局常量或共享服务,避免在两个组件中重复定义,降低维护成本。
  • 对localService.getData('city')的返回值增加空值校验,避免找不到对应城市时出现异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 22:40:44