我有一个 MatStepper
用于导航到注册流程的下一页。我还有一个方法可以从缓存中加载 values(如果可用),如果可用,则 MatStepper
会跳到第 2 页。之后,未来的方法会预填充那些缓存的 values 表单。
检索 cachedSports
的场景导致 MatStepper
工作并跳到第 2 页,但是当我尝试使用 cachedPets
或 cachedAnimals
预填充时, 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