Ionic 调用包含自定义类型变量的服务的Angular组件将无法编译,因为该变量在编译时“未定义”

8tntrjer  于 2023-03-27  发布在  Ionic
关注(0)|答案(1)|浏览(123)

我有一个Angular应用程序(来自Maximillian Schwarzmüller的Udemy课程,题为“Ionic - Build iOS,Android,and Web Apps with Ionic & Angular”),它无法编译,因为在Angular编译时,对我的服务中的方法的调用返回了一个“未定义”的值。
这门课程已经有好几年的历史了,在此期间,Ionic和Angular似乎发生了一些突破性的变化。这是唯一一个,到目前为止,我根本不知道如何修复。我希望这里有人能帮助我。
下面是自定义类型:

recipe.model.ts

export class Recipe {
    id: string = '';
    title: string = '';
    imageUrl: string = '';
    ingredients: string[] = [];
}

const recipe: Recipe = new Recipe();

这里是服务

recipies.service.ts

import { Injectable } from '@angular/core';
import { Recipe } from './recipe.model';

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

    private recipes: Recipe[] = [
        {
            id: 'r1',
            title: 'Schnitzel',
            imageUrl: 'https://upload.wikimedia.org/wikipedia/commons/thumb/7/72/Schnitzel.JPG/1024px-Schnitzel.JPG',
            ingredients: ['French Fries', 'Pork', 'Salad']
        },
        {
            id: 'r2',
            title: 'Spaghetti',
            imageUrl: 'https://upload.wikimedia.org/wikipedia/commons/thumb/2/20/Spaghetti_Bolognese_mit_Parmesan_oder_Grana_Padano.jpg/1024px-Spaghetti_Bolognese_mit_Parmesan_oder_Grana_Padano.jpg',
            ingredients: ['Spaghetti', 'Meat', 'Tomatoes']
        }
    ]

    constructor() { }

    getAllRecipes() {
        return this.recipes;
    }

    getRecipe(recipeId: string) {
        return this.recipes.find(recipe => {
                return recipe.id === recipeId;
            });
    }
}

下面是使用它们的组件:

recipe-detail.page.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { RecipesService } from '../recipes.service';
import { Recipe } from '../recipe.model';

@Component({
    selector: 'app-recipe-detail',
    templateUrl: './recipe-detail.page.html',
    styleUrls: ['./recipe-detail.page.scss'],
})
export class RecipeDetailPage implements OnInit {

    loadedRecipe: Recipe = new Recipe();

    constructor(private activatedRoute: ActivatedRoute, private recipesService: RecipesService) {
    }

    ngOnInit() {
        this.activatedRoute.paramMap.subscribe(paramMap => {
            if (!paramMap.has('recipeId')) {
                //todo: redirect
                return;
            }
            const recipeId = paramMap.get('recipeId');
            this.loadedRecipe = this.recipesService.getRecipe(recipeId as string); // !!!ERROR HERE!!!
        });
    }

}

我得到的错误(在代码中的注解行上)是:
TS2322: Type 'Recipe | undefined' is not assignable to type 'Recipe'.
还有一些可能相关也可能不相关的东西--在同一行中,如果我在方法调用中的recipeId之后省略了显式的类型转换as string,它会给我这个错误:
TS2345: Argument of type 'string | null' is not assignable to parameter of type 'string'.
这整个混乱的行为就像有什么我没有初始化的地方,但我不能找出在哪里或什么...
无论如何,由于这些错误,应用程序拒绝编译。所以我在这门课程中停留在Lesson # 77,我无法通过它。我希望这里的人足够了解Angular,他们可以看到发生了什么,并为我指出正确的方向。
不是寻找一个“更改你的tsconfig.json文件忽略这个错误”之类的东西,谢谢。我想知道为什么这不会工作。我想学习如何正确地修复它。为什么它的行为好像是未定义的?
先谢了...

o8x7eapl

o8x7eapl1#

typescript试图让你避免将SomeType | undefined赋值给SomeType。有时ts做得并不完美。有一些方法可以告诉typescript“我知道这里很好”。例如,你正在检查if中是否不存在param,因此肯定会在if之后有一个值,并且你可以添加bang !运算符来消除结果类型中的null

if (!paramMap.has('recipeId')) {
  //todo: redirect
  return;
}
const recipeId = paramMap.get('recipeId')!; // bang here, so recipeId would be of type string

你也可以在第二种情况下使用bang操作符,但是这里使用的是.find方法,并且有可能找不到任何东西。
正确的修复完全取决于你想要实现的目标,如果你想走最简单的路--添加!,就可以完成这项工作。

this.loadedRecipe = this.recipesService.getRecipe(recipeId)!;

不存在的配方只是不处理在这种情况下,将有一个错误的运行时,如果你试图访问该页不存在的id /recipe/qwerqwer

相关问题