【问题标题】:Use ion-card to display information from API on a second page使用 ion-card 在第二页显示来自 API 的信息
【发布时间】:2019-11-22 04:16:12
【问题描述】:

我正在尝试将其设置为当用户“点击”每家餐厅的卡片时,它将打开一个页面(selected-card.page),可以在其中找到其他详细信息(菜单、价格等)。我不太确定如何完成这项工作,目前正在尝试使用服务中的函数来调用 API 以显示该餐厅。

我意识到我可能还远远没有完成这项工作,如果您有指南或教程可以帮助您随时将其发送给我。感谢您的帮助!

dining.page.html(带有卡片的页面,您可以单击以访问更多详细信息)

  <ion-card (click)="onSelected(card)" class="welcome-card" *ngFor="let item of restaurantsService.restaurants">
    <img class='image' src='{{ item.restaurant.featured_image }}' alt='' />
    <ion-card-header>
      <ion-card-title class='text'>{{ item.restaurant.name }}</ion-card-title>
      <ion-card-subtitle class='text'>{{ item.restaurant.phone_numbers }}</ion-card-subtitle>
      <ion-card-subtitle class='text'>{{ item.restaurant.location.address }}</ion-card-subtitle>
    </ion-card-header>
  </ion-card>
</ion-content>

dining.page.ts

import { ModalController } from '@ionic/angular';
import { RestaurantsService } from '../services/restaurants.service';
import { Observable } from 'rxjs';
import { SelectedCardPage } from '../selected-card/selected-card.page';

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

  constructor( private restaurantsService: RestaurantsService,
               public modalCtrl: ModalController ) { };

  ngOnInit() {}

  async onSelected(card) {
      const modal = await this.modalCtrl.create({
        component: SelectedCardPage,
        componentProps: { value: card }
      });
      return await modal.present();
  }

  ionViewWillEnter() {
    this.restaurantsService.fetchRestaurants().subscribe();
  }


}

selected-card.page.html

<ion-content>
  <ion-card (click)="dismiss()" class="welcome-card" *ngFor="let item of restaurantsService.restaurants">
    <img class='image' src='{{ item.restaurant.featured_image }}' alt='' />
    <ion-card-header>
      <ion-card-title class='text'>{{ item.restaurant.name }}</ion-card-title>
      <ion-card-subtitle class='text'>{{ item.restaurant.phone_numbers }}</ion-card-subtitle>
      <ion-card-subtitle class='text'>{{ item.restaurant.location.address }}</ion-card-subtitle>
    </ion-card-header>
  </ion-card>
</ion-content>

selected-card.page.ts

import { ModalController, NavParams } from '@ionic/angular';
import { RestaurantsService } from '../services/restaurants.service';

@Component({
  selector: 'app-selected-card',
  templateUrl: './selected-card.page.html',
  styleUrls: ['./selected-card.page.scss'],
})
export class SelectedCardPage implements OnInit {
  value: string;
  constructor(private restaurantsService: RestaurantsService,
              private modalCtrl: ModalController,
              private navParams: NavParams) { }

  ngOnInit() {
  }

  ionViewWillEnter() {
    this.restaurantsService.fetchRestaurantDetails().subscribe();
  }

  ionViewDidLoad() {
    this.value = this.navParams.get('value');
  }

  dismiss() {
    this.modalCtrl.dismiss();
  }

}

restaurant.service.ts

import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class RestaurantsService {
  public restaurants = [];
  public providers = [];

  constructor( public http: HttpClient ) { }

//initial fetchRestaurants that loads on opening dining page
  fetchRestaurants() {
    console.log('fetching restaurants');
    let headers = {'content-type': 'application/json',
                    'accept': 'application/json',
                    'user-key': '7ae71880177b226bed309d0533717b4b'};
    let url = 'https://developers.zomato.com/api/v2.1/search?entity_id=757&entity_type=city&count=20'
    return this.http.get(url, {headers: headers}).pipe(tap(response => {
      console.log(response);
      this.restaurants = response['restaurants'];
      console.log(this.restaurants);
    }));
  }

  // used to obtain information/details on a restaurant when selected
  fetchRestaurantDetails() {
    console.log('getting restaurant details');
    let headers = {'content-type': 'application/json',
                    'accept': 'application/json',
                    'user-key': '7ae71880177b226bed309d0533717b4b'};
    let url = 'https://developers.zomato.com/api/v2.1/reviews?res_id=17266091'
    return this.http.get(url, {headers: headers}).pipe(tap(response => {
      console.log(response);
      this.restaurants = response['restaurants'];
      console.log(this.restaurants);
    }));
  }
}

【问题讨论】:

    标签: angular typescript ionic-framework zomato-api


    【解决方案1】:

    您没有将数据发送到您的餐厅详情页面 (SelectedCardPage)。您的点击函数传递了“卡片”,但不存在具有该名称的变量或对象。使用“item”,因为您的 For 循环通过名称“item”引用每家餐厅 你的代码:

    <ion-card (click)="onSelected(card)" class="welcome-card" *ngFor="let item of restaurantsService.restaurants">
    

    变化:

    <ion-card (click)="onSelected(item)" class="welcome-card" *ngFor="let item of restaurantsService.restaurants">
    

    现在,在您的 SelectedCardPage 模板中,您可以显示每个餐厅项目所持有的数据。

    <ion-content>
      <ion-card (click)="dismiss()" class="welcome-card">
        <img class='image' src='{{ item.restaurant.featured_image }}' alt='' />
        <ion-card-header>
          <ion-card-title class='text'>{{ item.restaurant.name }}</ion-card-title>
          <ion-card-subtitle class='text'>{{ item.restaurant.phone_numbers }}</ion-card-subtitle>
          <ion-card-subtitle class='text'>{{ item.restaurant.location.address }}</ion-card-subtitle>
        </ion-card-header>
      </ion-card>
    </ion-content>
    

    【讨论】:

    • 解决了部分问题。现在我正在尝试在restaurants.service.ts 上使用fetchRestaurantDetails 函数,它只会显示一个空白屏幕并将“未定义”打印到控制台......不一定是未定义的错误,而只是“未定义”这个词
    • 您的 fetchRestaurantDetails() 函数不接受任何餐厅 ID 或其他东西来唯一地获取餐厅。您需要将餐厅 ID 发送到您在 onViewDidLoad() 中获得的那个函数。另外,请发布您的完整控制台日志。
    【解决方案2】:

    因为您要使整张卡片可点击,并且您在其上运行循环以绑定详细信息。

    <ion-card (click)="onSelected(card)" class="welcome-card" *ngFor="let item of 
    restaurantsService.restaurants">
    <img class='image' src='{{ item.restaurant.featured_image }}' alt='' />
    <ion-card-header>
    <ion-card-title class='text'>{{ item.restaurant.name }}</ion-card-title>
    <ion-card-subtitle class='text'>{{ item.restaurant.phone_numbers }}</ion-card- 
    subtitle>
    <ion-card-subtitle class='text'>{{ item.restaurant.location.address }}</ion-card- 
    subtitle>
    </ion-card-header>
    </ion-card>
    </ion-content>
    

    错误:

     <ion-card (click)="onSelected(card)" class="welcome-card" *ngFor="let item of 
    restaurantsService.restaurants">
    

    您需要在 click 函数中传递“item”。 右:

     <ion-card (click)="onSelected(item)" class="welcome-card" *ngFor="let item of 
    restaurantsService.restaurants">
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-06
      • 1970-01-01
      • 1970-01-01
      • 2015-08-18
      • 2012-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多