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

Ionic菜谱应用:实现API ID传递与详情页跳转

没问题,我来帮你一步步实现这个菜谱详情跳转的功能,咱们分几个核心步骤来完成:

步骤1:配置路由(实现页面跳转基础)

首先得在路由里定义详情页的路径,让程序知道点击后该跳转到哪个页面。修改app-routing.module.ts:

import { NgModule } from '@angular/core';
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';
import { LandingPagePage } from './landing-page/landing-page.page';
// 导入你要创建的详情页组件(如果还没创建,先通过ionic cli生成:ionic generate page recipe-detail)
import { RecipeDetailPage } from './recipe-detail/recipe-detail.page';

const routes: Routes = [
  { path: '', component: LandingPagePage },
  // 定义带ID参数的详情页路由
  { path: 'recipe-detail/:id', component: RecipeDetailPage },
];

@NgModule({
  imports: [
    RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
  ],
  exports: [RouterModule]
})
export class AppRoutingModule { }
步骤2:扩展API服务,添加详情获取方法

你的现有服务只处理了列表请求,现在需要新增获取单菜谱详情的方法。修改ApiLandingRecipesService:

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
import { catchError, tap, map } from 'rxjs/operators';
import { Observable, throwError } from 'rxjs';

const httpOptions = { headers: new HttpHeaders({'Content-Type': 'application/json'}) };
const apiUrl = "https://forexample.com/recipeslist";
// 新增详情API的基础地址
const detailApiUrl = "https://forexample.com/recipedetails";

@Injectable({
  providedIn: 'root'
})
export class ApiLandingRecipesService {
  constructor(private http: HttpClient) { }

  private handleError(error: HttpErrorResponse) {
    if (error.error instanceof ErrorEvent) {
      console.error('An error occurred:', error.error.message);
    } else {
      console.error(
        `Backend returned code ${error.status}, ` +
        `body was: ${error.error}`);
    }
    return throwError('Something bad happened; please try again later.');
  }

  private extractData(res: any) {
    let body = res;
    return body || [] ;
  }

  getDataUser(): Observable<any> {
    return this.http.get(apiUrl, httpOptions).pipe(
      map(this.extractData),
      catchError(this.handleError));
  }

  // 新增:根据ID获取菜谱详情的方法
  getRecipeDetail(recipeId: string): Observable<any> {
    const targetUrl = `${detailApiUrl}/${recipeId}`;
    return this.http.get(targetUrl, httpOptions).pipe(
      map(this.extractData),
      catchError(this.handleError));
  }
}
步骤3:首页添加点击事件与导航逻辑

现在要给首页的菜谱名称添加点击事件,点击后携带ID跳转到详情页。修改landing-page.page.ts:

import { ApiLandingRecipesService} from '../api-landing-recipes.service';
import { Router } from '@angular/router'; // 导入路由服务

@Component({
  selector: 'app-landing-page',
  templateUrl: './landing-page.page.html',
  styleUrls: ['./landing-page.page.scss'],
})
export class LandingPagePage implements OnInit {
  datauser: any[];

  constructor(
    public api: ApiLandingRecipesService,
    private router: Router) { } // 注入路由服务

  ngOnInit() {
    this.getDataUser();
  }

  getDataUser() {
    // 这里不需要async/await,subscribe本身就是异步处理
    this.api.getDataUser()
      .subscribe(res => {
        console.log(res);
        this.datauser = res;
        console.log(this.datauser);
      }, err => {
        console.log(err);
      });
  }

  // 新增:跳转至详情页的方法
  navigateToDetail(recipeId: string) {
    this.router.navigate(['/recipe-detail', recipeId]);
  }
}

然后修改首页的HTML,给菜谱名称绑定点击事件:

<!-- 注意:把*ngFor放在ion-card上更合理,避免重复生成多个card-header -->
<ion-card *ngFor="let data of datauser">
  <ion-card-header>
    <!-- 绑定点击事件,传入当前菜谱的ID -->
    <p (click)="navigateToDetail(data.id)">{{data.recipename}}</p>
  </ion-card-header>
  <ion-card-content>
    <!-- 展示菜谱图片 -->
    <img [src]="data.image" alt="{{data.recipename}}">
  </ion-card-content>
</ion-card>
步骤4:详情页获取ID并加载数据

最后在详情页里,从路由参数中拿到ID,调用API获取详情并展示。修改recipe-detail.page.ts:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ApiLandingRecipesService } from '../api-landing-recipes.service';

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

  constructor(
    private route: ActivatedRoute, // 用于获取路由参数
    private api: ApiLandingRecipesService) { }

  ngOnInit() {
    // 从路由中提取ID参数
    this.recipeId = this.route.snapshot.paramMap.get('id');
    if (this.recipeId) {
      this.loadRecipeDetail();
    }
  }

  loadRecipeDetail() {
    this.api.getRecipeDetail(this.recipeId)
      .subscribe(res => {
        this.recipeDetail = res;
        console.log('菜谱详情:', this.recipeDetail);
      }, err => {
        console.error('加载详情失败:', err);
      });
  }
}

对应的详情页HTML(展示食材和做法):

<ion-header>
  <ion-toolbar>
    <ion-title>{{recipeDetail?.recipename}}</ion-title>
    <ion-buttons slot="start">
      <ion-back-button></ion-back-button> <!-- 自带返回按钮 -->
    </ion-buttons>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-card>
    <img [src]="recipeDetail?.image" alt="{{recipeDetail?.recipename}}">
    <ion-card-header>
      <ion-card-title>{{recipeDetail?.recipename}}</ion-card-title>
    </ion-card-header>
    <ion-card-content>
      <h3>食材清单</h3>
      <ul>
        <!-- 假设API返回的食材是数组,根据实际结构调整 -->
        <li *ngFor="let item of recipeDetail?.ingredients">{{item}}</li>
      </ul>
      <h3>烹饪步骤</h3>
      <p>{{recipeDetail?.instructions}}</p>
    </ion-card-content>
  </ion-card>
</ion-content>

注意事项

  • 确保你的API返回的字段名和代码中使用的一致(比如菜谱的ID字段是id,食材是ingredients等),如果API字段不同,需要对应修改代码中的字段名。
  • 如果还没创建详情页,记得先通过Ionic CLI生成:ionic generate page recipe-detail

内容的提问来源于stack exchange,提问作者لذيذ دوتكوم

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 20:03:13