angular - Angular MatStepper 无法从两个 str 数组中识别缓存的 values(但成功地从另一个 str 数组中识别 values)

我有一个 MatStepper 用于导航到注册流程的下一页。我还有一个方法可以从缓存中加载 values(如果可用),如果可用,则 MatStepper 会跳到第 2 页。之后,未来的方法会预填充那些缓存的 values 表单。

检索 cachedSports 的场景导致 MatStepper 工作并跳到第 2 页,但是当我尝试使用 cachedPetscachedAnimals 预填充时, MatStepper 失败并给我以下错误:

Cannot read properties of undefined (reading 'next')

cachedSports 和两个失败的场景之间没有太大的区别,所以我不知道罪魁祸首是什么。这三个都是字符串数组,并且它们缓存中的 values 成功进入。

// Cached values are retrieved from another file, memory-cache.service.ts
    loadFromCache(): void {
        const cachedPets: string[] = this.cacheService.get<string[]>(MemoryCacheService.WellKnownKeys.pets) ?? [];
        const cachedSports: string[] = this.cacheService.get<string[]>(MemoryCacheService.WellKnownKeys.sports) ?? [];
        const cachedAnimalNames: string[] = this.cacheService.get<string[]>(MemoryCacheService.WellKnownKeys.animals) ?? [];

        // Note that cachedPets and cachedAnimalNames share ('targetEveryAnimal')
        if (cachedPets.length > 0) {
          this.targetingFormGroup.get('targetEveryAnimal').setValue('Specific'); 
          this.targetPetChange({ value: 'Specific' }, cachedPets);
        } else if (cachedSports.length > 0) {
          this.targetingFormGroup.get('targetEverySport').setValue('Specific');
          this.targetSportChange({ value: 'Specific' }, cachedSports);
        } else if (cachedAnimalNames.length > 0) {
          this.targetingFormGroup.get('targetEveryAnimal').setValue('Specific');
          this.targetAnimalChange({ value: 'Specific' }, cachedAnimalNames);
        } 

        // The values correctly come through:
        console.log('cachedPets: ', cachedPets); // ["Cat"]
        console.log('cachedSports: ', cachedSports); // ["Tennis"]
        console.log('cachedAnimalNames: ', cachedAnimalNames); // ["Chinchilla"]

        this.goForward();
        this.location.replaceState('filters/setup/create/page2');
        this.skipPageOne = true;

        this.cacheService.remove(MemoryCacheService.WellKnownKeys.pets);
        this.cacheService.remove(MemoryCacheService.WellKnownKeys.sports);
        this.cacheService.remove(MemoryCacheService.WellKnownKeys.animals);

    }

  goForward(){
    this.myStepper.next();
    // Defined as: @ViewChild('stepper') private myStepper: MatStepper;
  }

这是缓存的 values 实际添加到表单中的位置

// Same file as the above code

validateFormTargeting() {

  const sports = (spt === 'Specific') ? this.targetingFormGroup.get('sports').value : [];
  console.log('tfg-sports: ', this.targetingFormGroup.get('sports').value) // ["Tennis"]
  console.log('sports: ', sports) // ["Tennis"]

  let pets;
  let animalNames;

  if (animt === 'Specific') {
    // pets = this.tarFormGroup.get // etc
    animalNames = this.targetingFormGroup.get('animalNames') ? this.targetingFormGroup.get('animalNames').value : [];
    
    // The console messages (therefore this code block) is not reached because of the "Cannot read properties of undefined" error
    console.log('tfg-animalNames: ', this.targetingFormGroup.get('animalNames').value)
    console.log('animalNames: ', animalNames)
  }
}

详细错误消息:

TypeError: Cannot read properties of undefined (reading 'next')
    at AppModalFormCreateComponent.goForward (myForm.component.ts:371:20)
    at AppModalFormCreateComponent.loadFromCache (myForm.component.ts:357:10)
    at AppModalFormCreateComponent.ngOnInit (myForm.component.ts:227:10)

回答1

这是 ViewChild 在调用 goForward 时没有被定义/设置。

如果模板正在更新,则可能是时间问题。出于测试目的,您可以将 goForward 中的代码包装在 setTimeout()

回答2

确保您的代码仅在 ngAfterViewInit 之后运行,因为您可能会尝试在重新渲染视图之前访问元素,从而导致在视图上查询的 viewchild 的属性未定义。

注意:ngAfterViewInit 可能不是最好的生命周期选项,所以请从列表中选择更适合您的选项。 https://angular.io/guide/lifecycle-hooks

相似文章

随机推荐

最新文章