Ionic 3.1
WordPress 4.9
を使用します。
作るもの
前回はタブアプリをベースニュース一覧ページを作成しました。
表示する内容はアプリ内に持っていたので、これおwサーバーから取得して表示できるように変更してみます。
Ionicでリストナビゲーションの作り方
WordPressの設定
最初にWordPress側でアプリ用のデータを書き出すようにします。
アプリとのやりとりはJson形式でやりとりするのが一般的です。
最近のバージョンのWordPressではREST APIが使えますが、今回は自作でファイルを作成てみます。
作成するのは一覧のposts.php
と、個別ページ用のsingle.php
です。
配置する場所はどこでもいいですがapi
ディレクトリを作成して配置します。
api/posts.php
<?php require_once '../wp-load.php'; $paged = (int)$_GET['paged']; $posts = get_posts([ 'numberposts' => 10, 'orderby' => 'post_date', 'order' => 'DESC', 'paged' => $paged ]); $records = []; if($posts) { foreach($posts as $post) { $records[] = [ 'id' => $post->ID, 'title' => $post->post_title, 'date' => get_the_date('Y年m月d日') ]; } } header('Access-Control-Allow-Origin: *'); header('Content-Type: application/json; charset=utf-8'); echo json_encode($records);
最初のインクルードしているwp-load.php
はWordPressを配置した場所によって変わるので適切に変更してください。
次に詳細ページ用のPHPです。
api/single.php
<?php require_once '../wp-load.php'; $id = (int)$_GET['id']; $post = get_posts([ 'p' => $id ]); $post = $post[0]; $record = []; if($post) { $record = [ 'title' => $post->post_title, 'date' => get_the_date('Y年m月d日'), 'content' => apply_filters('the_content', $post->post_content) ]; } header('Access-Control-Allow-Origin: *'); header('Content-Type: application/json; charset=utf-8'); echo json_encode($record);
/api/single.php?id=1
のようにidというパラメータを付与することで、そのIDの記事を表示するという動きになってます。
このファイルをWordPressの入っているサーバーに配置します。
ここではhttp://localhost:8080/api/
に配置するものとします。
記事一覧
Ionicでアプリ側で記事一覧の取得を行います。
一覧はnews.ts
ですね。
前回と変わったところはHttpClient
をインポートして、表示されたとき(ionViewDidLoad)にhttp.get
で先ほど設定したPHPから情報を取得しています。
page/news.ts
import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { NavController, NavParams, LoadingController } from 'ionic-angular'; import { NewsDetailPage } from '../news-detail/news-detail'; @Component({ selector: 'page-news', templateUrl: 'news.html', }) export class NewsPage { items: { id: number, title: string, date: string }[]; constructor( public navCtrl: NavController, public navParams: NavParams, public http: HttpClient, public lodingCtrl: LoadingController ) {} openNavDetailsPage(id) { this.navCtrl.push(NewsDetailPage, { id: id }); } ionViewDidLoad() { // ローディング表示 let loding = this.lodingCtrl.create(); loding.present(); // 情報を取得 this.http .get<{ id: number, title: string, date: string }[]>('http://localhost:8080/api/posts.php') .subscribe(data => { this.items = data; loding.dismiss(); // ローディング削除 }); } }
詳細画面でも読み込みを行うので、openNavDetailsPage
ではid
を渡すようにします。
news.html
でもidが渡るように変更します。
page/news.html
<ion-list> <button ion-item *ngFor="let item of items" (click)="openNavDetailsPage(item.id)"> <h2>{{ item.title }}</h2> <p>{{ item.date }}</p> </button> </ion-list>
記事詳細の表示
記事詳細ページでもhttpクライアントを使って、今度はapi/single.php
の情報を取得します。
一覧と大きくは変わらないですね。IDを受け取って、URLのパラメータに付与していることと、扱っているのが配列ではないことくらいでしょうか。
あとはコンストラクタでitem
オブジェクトにnullをいれないとエラーになるようです。
page/news-detail.ts
import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http';ionic-angular'; import { NavController, NavParams, LoadingController } from 'ionic-angular'; @Component({ selector: 'page-news-detail', templateUrl: 'news-detail.html', }) export class NewsDetailPage { item: { title: string, date: string, content: string }; constructor( public navCtrl: NavController, public navParams: NavParams, public http: HttpClient, public lodingCtrl: LoadingController ) { this.item = { title: null, date: null, content: null } } ionViewDidLoad() { const id:number = this.navParams.data.id; let loding = this.lodingCtrl.create(); loding.present(); this.http .get<{ title: string, date: string, content: string }>('http://localhost:8080/api/single.php?id=' + id) .subscribe(data => { this.item = data; loding.dismiss(); }); } }
詳細画面のHTMLです。
{{}}
で囲むとHTMLタグはエスケープされますが、<div [innerHTML]="item.content"></div>
とすることでHTMLがそのまま表示されます。
page/news-detail.html
<ion-content padding> <p>{{ item.date }}</p> <h2>{{ item.title }}</h2> <div [innerHTML]="item.content"></div> </ion-content>
app.moduleへの登録
最後にapp.module.ts
に新たに作成したHttpClientModule
を登録しましょう。
src/app/app.module.ts
import { HttpClientModule } from '@angular/common/http'; @NgModule({ imports: [ // ... HttpClientModule ], // ... })
以上です。
今回は表示しているだけですが、サーバーと連携できるようになるといろいろとできることが増えて楽しいですね。