Ionic Frameworkで記述されたアプリケーションがあります。 それに基づいて、開発経験をすべての人と共有し、クロスプラットフォームアプリケーションを作成する方法を段階的に作成したいと思います。
この記事では、記事(出版物)を読むことができるアプリケーションをゼロから開発します。 出版物には、タイトル(タイトル)、タイトル写真、概要、完全なコンテンツ、カテゴリ、著者、出版日が含まれます。 アプリケーションのすべてのデータは、Httpリクエストを介してサーバーから取得されます。
アプリケーションには、いくつかのページ(画面)があります。
- 日付でソートされたすべての出版物のリスト。
- アルファベット順にソートされたカテゴリのリスト。
- 名前でソートされた著者のリスト。
- 日付順にソートされた、選択したカテゴリの出版物のリスト。
- 日付順にソートされた、選択した著者の出版物のリスト。
- 出版物の内容。
この記事の結果は、上の画像のようなアプリケーションです。
さらに、プロジェクト全体のソースコードへのリンク。
開始する
新しいプロジェクトを作成し、それをarticleと呼びます。 これを行うには、次のコマンドを実行します。
ionic start articles tabs
その結果、 articlesという名前の作成されたディレクトリが表示されます 。
プロジェクト構造
必要な新しいページを作成します: postlist 、 categorylist 、 authorlist 。 これを行うには、コマンドを1つずつ実行します。
ionic generate page postlist
ionic generate page categorylist
ionic generate page authorlist
その結果、 \ articles \ src \ pages \フォルダに作成されたディレクトリが表示されます。
作成されたページ
ファイルを開きます: postlist.ts 、 categorylist.ts 、 authorlist.tsそして、各ファイルにNavControllerクラスとNavParamsオブジェクトをインポートする行を書きます
import { NavController, NavParams } from 'ionic-angular';
その結果、次のタイプのファイルpostlist.ts 、 categorylist.ts 、 authorlist.tsを取得します
import { Component } from '@angular/core'; import { NavController, NavParams } from 'ionic-angular'; @Component({ selector: 'page-postlist', templateUrl: 'postlist.html', }) export class Postlist { constructor(public navCtrl: NavController, public navParams: NavParams) { } ionViewDidLoad() { console.log('ionViewDidLoad Postlist'); } }
import { Component } from '@angular/core'; import { NavController, NavParams } from 'ionic-angular'; @Component({ selector: 'page-categorylist', templateUrl: 'categorylist.html', }) export class Categorylist { constructor(public navCtrl: NavController, public navParams: NavParams) { } ionViewDidLoad() { console.log('ionViewDidLoad Categorylist'); } }
import { Component } from '@angular/core'; import { NavController, NavParams } from 'ionic-angular'; @Component({ selector: 'page-authorlist', templateUrl: 'authorlist.html', }) export class Authorlist { constructor(public navCtrl: NavController, public navParams: NavParams) { } ionViewDidLoad() { console.log('ionViewDidLoad Authorlist'); } }
\ articles \ src \ pages \ : about 、 contact 、 homeの余分なフォルダーを削除します。 これらは、プロジェクトの作成時に自動的に作成されました。 それらは必要ありません。
ファイル\ src \ app \ app.module.tsを開き、そこで変更を加えます。 新しく作成されたページの使用を登録し、削除されたページへのすべての参照を削除します。
すべてのアクションの結果は、 app.module.tsファイルの内容になります
app.module.ts
import { NgModule, ErrorHandler } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular'; import { MyApp } from './app.component'; import { Postlist } from '../pages/postlist/postlist'; import { Categorylist } from '../pages/categorylist/categorylist'; import { Authorlist } from '../pages/authorlist/authorlist'; import { TabsPage } from '../pages/tabs/tabs'; import { StatusBar } from '@ionic-native/status-bar'; import { SplashScreen } from '@ionic-native/splash-screen'; @NgModule({ declarations: [ MyApp, Postlist, Categorylist, Authorlist, TabsPage ], imports: [ BrowserModule, IonicModule.forRoot(MyApp) ], bootstrap: [IonicApp], entryComponents: [ MyApp, Postlist, Categorylist, Authorlist, TabsPage ], providers: [ StatusBar, SplashScreen, {provide: ErrorHandler, useClass: IonicErrorHandler} ] }) export class AppModule {}
ファイル\ src \ pages \ tabs \ tabs.tsを開いて、タブがページpostlist 、 categorylist 、 authorlistに リンクするように内容を変更します。
変更されたファイルは次のようになります。
import { Component } from '@angular/core'; import { Postlist } from '../postlist/postlist'; import { Categorylist } from '../categorylist/categorylist'; import { Authorlist } from '../authorlist/authorlist'; @Component({ templateUrl: 'tabs.html' }) export class TabsPage { tab1Root = Postlist; tab2Root = Categorylist; tab3Root = Authorlist; constructor() { } }
ファイル\ src \ pages \ tabs \ tabs.htmlを開き 、そこで次の変更を行います:tabTitleのタブの名前とtabIconのアイコンを変更します(必要なアイコンはすべてioniconsドキュメントにリストされています):
<ion-tabs> <ion-tab [root]="tab1Root" tabTitle="" tabIcon="ios-paper-outline"></ion-tab> <ion-tab [root]="tab2Root" tabTitle="" tabIcon="ios-albums-outline"></ion-tab> <ion-tab [root]="tab3Root" tabTitle="" tabIcon="ios-contacts-outline"></ion-tab> </ion-tabs>
ionic serve
コマンドを実行して、結果を確認します。
最初の結果
アプリケーションのメイン色を希望の色に変更します。 これを行うには、ファイル\ src \ theme \ variables.scssを
clmain:#3949ab
、目的の色
clmain:#3949ab
を追加します
clmain:#3949ab
を
$colors
配列に追加します。
$colors: ( primary: #488aff, secondary: #32db64, danger: #f53d3d, light: #f4f4f4, dark: #222, clmain: #3949ab, );
そして、 postlist.html 、 categorylist.html 、 authorlist.htmlの各ページの上部(
<ion-navbar>
)にこの色を適用します。
<ion-navbar color="clmain"> ... </ion-navbar>
タブの色を再定義します。 そのような行をファイル\ src \ theme \ variables.scssに書き込みます 。
$tabs-md-tab-color-active: #283593; $tabs-ios-tab-color-active: #283593; $tabs-wp-tab-color-active: #283593;
その結果、アプリケーションの外観は次のようになります。
アプリケーションのメイン色
メニュー
次に、gambergerボタンをクリックすると左側にポップアップするメニューを作成します。
名前、インデックス、アイコンを含むページがリストされる配列を作成します。 app.component.tsファイルを開き、最初に
MyApp
クラスで
pages
配列を宣言し
MyApp
。
pages: Array<{title: string, component: any, index: string, icon_name: string}>;
そしてクラスコンストラクターでこの配列を埋めます:
this.pages = [ { title: '', component: TabsPage, index: '0', icon_name: 'ios-paper-outline' }, { title: '', component: TabsPage, index: '1', icon_name: 'ios-albums-outline' }, { title: '', component: TabsPage, index: '2', icon_name: 'ios-contacts-outline' } ];
また、最初に使用したタブをインポートします。
import { TabsPage } from '../pages/tabs/tabs';
埋められた
pages
配列を使用して、メニュー項目を表示します。 app.htmlファイルを開き、次のフォームに移動します。
<ion-menu [content]="content"> <ion-header> </ion-header> <ion-content> <ion-list no-lines> <button menuClose ion-item *ngFor="let p of pages" (click)="openPage(p)" color="clmain"> <ion-icon item-left [name]="p.icon_name" item-left color="light"></ion-icon> {{p.title}} </button> </ion-list> </ion-content> </ion-menu> <ion-nav [root]="rootPage" #content></ion-nav>
openPage(p)
メソッドは、メニュー項目がクリックされるとトリガーされます。 押されたメニュー項目の配列要素がパラメーターとして渡されます。
app.component.tsファイルでこのメソッドの操作を説明します
openPage(page) { this.navCtrl.setRoot(page.component, {index: page.index}); }
navCtrl.setRoot
呼び出されると
navCtrl.setRoot
page.component
ページと、選択されたアイテムのインデックスである
page.index
パラメーターを
page.index
ます。 3つのタブのどれが開くかを知るには、このパラメーターが必要です。
navCtrl
次のように宣言されます(すべて同じapp.component.tsファイル内):
import { ViewChild } from '@angular/core'; import { Nav } from 'ionic-angular';
そして、最初の
MyApp
クラスで広告を作成します。
@ViewChild(Nav) navCtrl: Nav;
その結果、 app.component.tsファイルの次のコンテンツを取得します。
app.component.ts
import { Component, ViewChild } from '@angular/core'; import { Nav, Platform } from 'ionic-angular'; import { StatusBar } from '@ionic-native/status-bar'; import { SplashScreen } from '@ionic-native/splash-screen'; import { TabsPage } from '../pages/tabs/tabs'; @Component({ templateUrl: 'app.html' }) export class MyApp { @ViewChild(Nav) navCtrl: Nav; rootPage:any = TabsPage; pages: Array<{title: string, component: any, index: string, icon_name: string}>; constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) { platform.ready().then(() => { // Okay, so the platform is ready and our plugins are available. // Here you can do any higher level native things you might need. statusBar.styleDefault(); splashScreen.hide(); }); this.pages = [ { title: '', component: TabsPage, index: '0', icon_name: 'ios-paper-outline' }, { title: '', component: TabsPage, index: '1', icon_name: 'ios-albums-outline' }, { title: '', component: TabsPage, index: '2', icon_name: 'ios-contacts-outline' } ]; } openPage(page) { this.navCtrl.setRoot(page.component, {index: page.index}); } }
ここで、特定のメニュー項目「Publications」 、 「Categories」 、 「Authors」をクリックしたときに開くタブを正確に選択します。 これを行うには、 tabs.tsファイルを開き、
Index
パラメーター(
openPage(page)
メソッドで渡される
openPage(page)
の受信を書き込みます。
NavParams
インポート:
import { NavParams } from 'ionic-angular';
TabsPage
クラスで新しい
index
変数を宣言します。
index: string;
コンストラクターのパラメーターに、次のように記述します。
public navParams: NavParams
そして、コンストラクターの本体に、インデックス値の受信を書き込みます。
this.index = navParams.get('index');
tabs.tsファイル全体は次のようになります。
import { Component } from '@angular/core'; import { NavParams } from 'ionic-angular'; import { Postlist } from '../postlist/postlist'; import { Categorylist } from '../categorylist/categorylist'; import { Authorlist } from '../authorlist/authorlist'; @Component({ templateUrl: 'tabs.html' }) export class TabsPage { index: string; tab1Root = Postlist; tab2Root = Categorylist; tab3Root = Authorlist; constructor(public navParams: NavParams) { this.index = navParams.get('index'); } }
結果のインデックスに必要なタブの選択を追加します。 これを行うには、
<ion-tabs>
tabs.htmlファイルに次を記述します。
<ion-tabs selectedIndex={{index}}>
すべてのメニューの背景をメインの色と同じにします。 これを行うには、ファイル\ src \ app \ app.scssを開き、そこにスタイルを追加します。
.myBg{ background-color: #3949ab; }
app.htmlファイルを開き、このスタイルを
<ion-content>
要素に適用します。
<ion-content class="myBg">
左メニュー
次の行(
<ion-navbar>
)をファイルpostlist.html 、 categorylist.html 、 authorlist.htmlに追加して、アプリケーションの一番上の行の左側にメニューアイコン(ハンバーガー)を表示します。
<button ion-button menuToggle> <ion-icon name="menu"></ion-icon> </button>
結果を見て、このビューを見てみましょう。
メニューアイコン
実験として、すべてのメニュー項目を表示する前に画像を追加します。 これを行うには、任意のサイズの写真を撮り、
\src\assets\imgs\
という名前で
\src\assets\imgs\
し
\src\assets\imgs\
。 次に、 app.htmlファイルで使用します。
<ion-content class="myBg"> <img src="assets/imgs/menu.png" /> <ion-list no-lines> <button menuClose ion-item *ngFor="let p of pages" (click)="openPage(p)" color="clmain"> <ion-icon item-left [name]="p.icon_name" item-left color="light"></ion-icon> {{p.title}} </button> </ion-list> </ion-content>
結果を見て、以下を見てみましょう。
写真付きのメニュー
完了した作業の結果、次のものを含むアプリケーションが得られました。
- 3ページ:「Publications」、「Categories」、「Authors」。
- 左側のメニュー。
- ページを切り替えるためのタブ。
- タブを切り替えるためのメニュー項目。
データ検索
次に、各ページ( postlist 、 categorylist 、 authorlist )に、 HTTPリクエストを介してJSON形式で受信するデータを入力します。
各ページに実装されるアイテムのリストは次のとおりです。
- ページを開くときにデータをロードします。
- リストの最後の要素までスクロールするときに、次のデータをロードします。
- リストの先頭が表示されたら、リストをプルダウンしながらページを更新します。
- ロードのスピナーを表示する(データ受信時のクエリ時)。
- リクエスト実行時のエラー処理。
Ionicでのクエリ実行に関するいくつかの言葉。 クエリを使用する場合、 CORSテクノロジーについて覚えておく必要があります。
この例では、サーバーを使用してデータを受信します。したがって、ヘッダーでサーバーからデータを受信するとき、問題なくヘッダーを指定します:
header('Content-Type: application/json;charset=utf-8'); header('Access-Control-Allow-Origin: *');
たとえば、カテゴリのリストを取得するための完全なスクリプトは次のようになります。
カテゴリのリストを取得するスクリプト
header('Content-Type: application/json;charset=utf-8'); header('Access-Control-Allow-Origin: *'); $dblocation = "localhost"; $dbname = "database"; $dbuser = "username"; $dbpasswd = "password"; $mysqli = new mysqli($dblocation, $dbuser, $dbpasswd, $dbname); $query = " select `tb_categories`.* from `tb_categories` order by `tb_categories`.`category`"; $data = array(); if ($res = $mysqli->query($query)) { $data['count'] = strval($res->num_rows); while($row = $res->fetch_assoc()){ $data['data'][] = array( 'id' => $row['id'], 'category' => $row['category'], 'url' => $row['url'] ); } } echo json_encode($data);
このスクリプトを実行すると、JSON形式のデータを回答として受け取ります。
JSONデータ
Ionicアプリケーションに戻ります。 Httpサービスを接続することから始めましょう。 最初に、次の行を使用してapp.module.tsファイルにHttpModuleをインポートします。
import { HttpModule } from '@angular/http';
また、インポートセクションに記述します。
imports: [ BrowserModule, HttpModule, IonicModule.forRoot(MyApp) ],
次に、 postlist.tsファイルに移動して、次のオブジェクトのインポートについて説明します。
import { Http } from '@angular/http'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/timeout'; import { LoadingController } from 'ionic-angular';
LoadingControllerは 、ローディングインジケーターを表示するために使用されます。
Postlist
クラスのコンストラクターで
Http
および
LoadingController
サービスを宣言します。
constructor(public navCtrl: NavController, public http: Http, public loadingCtrl: LoadingController, public navParams: NavParams)
さらに、 postlist.tsファイルの全内容をコメント付きで提供します。
postlist.ts
import { Component } from '@angular/core'; import { NavController, NavParams } from 'ionic-angular'; import { Http } from '@angular/http'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/timeout'; import { LoadingController } from 'ionic-angular'; @Component({ selector: 'page-postlist', templateUrl: 'postlist.html', }) export class Postlist { postlists: any; // , postlists_new: any; // , countElement: number = 10; // - , beginElement: number = 0; // , post_error: string; // 0-, 1- constructor(public navCtrl: NavController, public http: Http, public loadingCtrl: LoadingController, public navParams: NavParams) { // // 0 - // 1 - this.loadData(0); } loadData(isNew) { if (isNew==0){ // this.beginElement = 0; this.countElement = 10; // let loadingPopup = this.loadingCtrl.create({ content: '' }); // loadingPopup.present(); // , URL- this.http.get('https://mysite.ru/postlist.php?begin='+this.beginElement+'&limit='+this.countElement) .timeout(20000) // 20 . .map(res => res.json()) .subscribe( data => { setTimeout(() => { this.postlists = data.data; // , this.countElement = data.count; // - this.post_error = "0"; // - loadingPopup.dismiss(); // }, 1000); }, err => { loadingPopup.dismiss(); // this.post_error = "1"; // - } ); }else{ // this.beginElement = Number(this.beginElement) + Number(this.countElement); } } // doInfinite(infiniteScroll) { // // 0 , // if (this.countElement != 0){ this.loadData(1); // Get the data this.http.get('https://mysite.ru/postlist.php?begin='+this.beginElement+'&limit='+this.countElement) .timeout(20000) .map(res => res.json()) .subscribe( data => { setTimeout(() => { this.postlists_new = data.data; // this.countElement = data.count; this.post_error = "0"; for (let i = 0; i < this.countElement; i++) { this.postlists.push( this.postlists_new[i] ); // } infiniteScroll.complete(); }, 1000); }, err => console.error(err) ); }else{ infiniteScroll.complete(); } } // , doRefresh(refresher) { this.loadData(0); setTimeout(() => { refresher.complete(); }, 2000); } ionViewDidLoad() { console.log('ionViewDidLoad Postlist'); } }
postlist.htmlファイルを開き、受信したデータをリストに表示します。
... <ion-content padding> <ion-refresher (ionRefresh)="doRefresh($event)"> <ion-refresher-content pullingIcon="arrow-dropdown" pullingText=" " refreshingSpinner="circles" refreshingText="..."> </ion-refresher-content> </ion-refresher> <div *ngIf="post_error == '0'"> <ion-card *ngFor="let postlist of postlists" (click)="openPostPage(postlist)" text-wrap class="list-selected"> <ion-card-title class="postlist-title"></ion-card-title> <div> <div class="postlist-category">{{postlist.category}}</div> <div class="postlist-dat">{{postlist.dat3}}</div> </div> <ion-card-title class="postlist-title"> {{postlist.title}} </ion-card-title> <img [src]="postlist.img" /> <h5 class="postlist-intro-text">{{postlist.intro_text}}</h5> </ion-card> </div> <div *ngIf="post_error == '1'" style="text-align: center"> <ion-label> </ion-label> <button ion-button (click)="loadData(0)" color="clmain" icon-left> <ion-icon name="refresh"></ion-icon> </button> </div> <ion-infinite-scroll (ionInfinite)="doInfinite($event)"> <ion-infinite-scroll-content loadingSpinner="bubbles" loadingText=" ..."> </ion-infinite-scroll-content> </ion-infinite-scroll> </ion-content>
このコードについて少し説明します。 <ion-refresher>ブロックの上部には、リストの先頭が表示されているときにリストを下にドラッグしたときのアクションが記述されています。 下部の<ion-infinite-scroll>ブロックは、リストの最後の要素までスクロールするときのアクションを説明しています。
中央部には2つの
div
ブロックがあります。 1つは、データの受信にエラーがないという条件下で表示されます(
post_error == '0'
)。 エラーが発生した場合は2番目が表示されます(
post_error == '1'
)。
結果は
次に、ディスプレイを少し装飾します。 これを行うために、必要なスタイル(
postlist-title, postlist-intro-text, postlist-dat, postlist-category
)をpostlist.scssファイルに記述します:
page-postlist { .postlist-title { font-size: 18px !important; white-space: inherit; } .postlist-intro-text { font-size: 14px !important; color: gray; white-space: inherit; } .postlist-dat { font-size: 12px !important; color: gray; white-space: inherit; float: right; text-align: right; width: 50%; } .postlist-category { font-size: 12px !important; color: gray; white-space: inherit; float: left; width: 50%; } }
結果は
データの読み込み
データ受信エラー
データ更新
以下のデータをダウンロードしてください
リスト項目( <ion-card> )を
click
と、
click
イベントが発生します。 そして、
openPostPage(postlist)
メソッドの呼び出しを
openPostPage(postlist)
。 このメソッドは、パブリケーションのコンテンツを開きます。 後で彼に戻り、彼について説明します。
残りの2つのページに対して同じ手順を実行します。
categorylistには、出版物のすべてのカテゴリのリストが表示されます。
authorlistでは、すべての出版物ユーザーのリストを表示します。
データを取得して表示する手順はポストリストページの手順と同じであるため、以下では各ページの既製ファイルをすぐに提供します。
唯一の例外はカテゴリです。 なぜなら カテゴリは原則として少数であるため、このページではリストの最後に達しても次のデータをダウンロードする必要はありません。 すべてのカテゴリをすぐに取得し、それらを完全に表示します。
さらに、別の機能を作成します。リストアイテム(カテゴリまたは作成者)をクリックすると、選択したアイテムの出版物のリストが開きます。 これを行うには、
click
イベントに対して、各ページの
openPostAuthorPage
メソッドと
openPostAuthorPage
メソッドの呼び出しをそれぞれ記述し、メソッドの操作( categorylist.tsファイルとauthorlist.tsファイルの両方)も記述します 。
openPostCategoryPage(item) { this.navCtrl.push(Postlist, { item: item, type: '1' }); }
openPostAuthorPage(item) { this.navCtrl.push(Postlist, { item: item, type: '2' }); }
パラメータとして、選択したページ(
item
)とページ番号(
type
)を渡して、カテゴリページと作成者ページを後で区別します。
categorylist.ts 、 categolist.htmlおよびauthorlist.ts、authorlist.htmlファイルの完全なコンテンツを次に示します 。
categorylist.ts
import { Component } from '@angular/core'; import { NavController, NavParams } from 'ionic-angular'; import { Http } from '@angular/http'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/timeout'; import { LoadingController } from 'ionic-angular'; import { Postlist } from '../postlist/postlist'; @Component({ selector: 'page-categorylist', templateUrl: 'categorylist.html', }) export class Categorylist { categorylists: any; post_error: string; constructor(public navCtrl: NavController, public navParams: NavParams, public http: Http, public loadingCtrl: LoadingController) { this.loadData(); } openPostCategoryPage(item) { this.navCtrl.push(Postlist, { item: item, type: '1' }); } loadData() { // let loadingPopup = this.loadingCtrl.create({ content: '' }); // loadingPopup.present(); // , URL- this.http.get('https://mysite.ru//categorylist.php') .timeout(20000) .map(res => res.json()) .subscribe( data => { setTimeout(() => { this.categorylists = data.data; this.post_error = "0"; loadingPopup.dismiss(); }, 1000); }, err => { loadingPopup.dismiss(); this.post_error = "1"; } ); } // , doRefresh(refresher) { this.loadData(); setTimeout(() => { refresher.complete(); }, 2000); } ionViewDidLoad() { console.log('ionViewDidLoad Categorylist'); } }
categorylist.html
<ion-header> <ion-navbar color="clmain"> <button ion-button menuToggle> <ion-icon name="menu"></ion-icon> </button> <ion-title></ion-title> </ion-navbar> </ion-header> <ion-content padding> <ion-refresher (ionRefresh)="doRefresh($event)"> <ion-refresher-content pullingIcon="arrow-dropdown" pullingText=" " refreshingSpinner="circles" refreshingText="..."> </ion-refresher-content> </ion-refresher> <div *ngIf="post_error == '0'"> <ion-list> <button ion-item *ngFor="let categorylist of categorylists" (click)="openPostCategoryPage(categorylist)" text-wrap class="list-selected"> <ion-avatar item-left> <img [src]="categorylist.icon" /> </ion-avatar> <ion-label class="categorylist-title">{{categorylist.category}}</ion-label> </button> </ion-list> </div> <div *ngIf="post_error == '1'" style="text-align: center"> <ion-label> </ion-label> <button ion-button (click)="loadData(0)" color="clmain" icon-left> <ion-icon name="refresh"></ion-icon> </button> </div> </ion-content>
authorlist.ts
import { Component } from '@angular/core'; import { NavController, NavParams } from 'ionic-angular'; import { Http } from '@angular/http'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/timeout'; import { LoadingController } from 'ionic-angular'; import { Postlist } from '../postlist/postlist'; @Component({ selector: 'page-authorlist', templateUrl: 'authorlist.html', }) export class Authorlist { authorlists: any; authorlists_new: any; countElement: number = 40; beginElement: number = 0; post_error: string; constructor(public navCtrl: NavController, public navParams: NavParams, public http: Http, public loadingCtrl: LoadingController) { this.loadData(0); } openPostAuthorPage(item) { this.navCtrl.push(Postlist, { item: item, type: '2' }); } loadData(isNew) { if (isNew==0){ // this.beginElement = 0; this.countElement = 40; // let loadingPopup = this.loadingCtrl.create({ content: '' }); // loadingPopup.present(); // , URL- this.http.get('https://mysite.ru/authorlist.php?begin='+this.beginElement+'&limit='+this.countElement) .timeout(20000) .map(res => res.json()) .subscribe( data => { setTimeout(() => { this.authorlists = data.data; this.countElement = data.count; this.post_error = "0"; loadingPopup.dismiss(); }, 1000); }, err => { loadingPopup.dismiss(); this.post_error = "1"; } ); }else{ // this.beginElement = Number(this.beginElement) + Number(this.countElement); } } // doInfinite(infiniteScroll) { // // 0 , // if (this.countElement != 0){ this.loadData(1); // , URL- this.http.get('https://mysite.ru/authorlist.php?begin='+this.beginElement+'&limit='+this.countElement+'&t='+this.searchtext) .timeout(20000) .map(res => res.json()) .subscribe( data => { setTimeout(() => { this.authorlists_new = data.data; this.countElement = data.count; this.post_error = "0"; for (let i = 0; i < this.countElement; i++) { this.authorlists.push( this.authorlists_new[i] ); } infiniteScroll.complete(); }, 1000); }, err => console.error(err) ); }else{ infiniteScroll.complete(); } } // , doRefresh(refresher) { this.loadData(0); setTimeout(() => { refresher.complete(); }, 2000); } ionViewDidLoad() { console.log('ionViewDidLoad Authorlist'); } }
authorlist.html
<ion-header> <ion-navbar color="clmain"> <button ion-button menuToggle> <ion-icon name="menu"></ion-icon> </button> <ion-title></ion-title> </ion-navbar> </ion-header> <ion-content padding class="android-scroll-bar"> <ion-refresher (ionRefresh)="doRefresh($event)"> <ion-refresher-content pullingIcon="arrow-dropdown" pullingText=" " refreshingSpinner="circles" refreshingText="..."> </ion-refresher-content> </ion-refresher> <div *ngIf="post_error == '0'"> <ion-list> <button ion-item *ngFor="let authorlist of authorlists" (click)="openPostAuthorPage(authorlist)" text-wrap class="list-selected"> <ion-avatar item-left> <img [src]="authorlist.img" /> </ion-avatar> <ion-label class="authorlist-title">{{authorlist.author}}</ion-label> </button> </ion-list> </div> <div *ngIf="post_error == '1'" style="text-align: center"> <ion-label> </ion-label> <button ion-button (click)="loadData(0)" color="clmain" icon-left> <ion-icon name="refresh"></ion-icon> </button> </div> <ion-infinite-scroll (ionInfinite)="doInfinite($event)"> <ion-infinite-scroll-content loadingSpinner="bubbles" loadingText=" ..."> </ion-infinite-scroll-content> </ion-infinite-scroll> </ion-content>
カテゴリと著者を表示した結果
選択したカテゴリと選択した著者の出版物のリストを表示するには、既存のポストリストページを使用します。
これを行うには、Httpリクエストで、選択したカテゴリの値を転送するパラメーターCと、選択した作成者を転送するパラメーターAを導入します。このパラメーターが入力されていない場合、すべてのパブリケーションを返します。
ファイルpostlist.tsおよびpostlist.htmlを変更すると、次の結果が得られます。
postlist.ts
import { Component } from '@angular/core'; import { NavController, NavParams } from 'ionic-angular'; import { Http } from '@angular/http'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/timeout'; import { LoadingController } from 'ionic-angular'; @Component({ selector: 'page-postlist', templateUrl: 'postlist.html', }) export class Postlist { title: string; categoryId: any; authorId: any; selectedItem: any; selectedType: string; postlists: any; // , postlists_new: any; // , countElement: number = 10; // - , beginElement: number = 0; // , post_error: string; // 0-, 1- constructor(public navCtrl: NavController, public http: Http, public loadingCtrl: LoadingController, public navParams: NavParams) { this.selectedItem = navParams.get('item'); this.selectedType = navParams.get('type'); this.categoryId = ''; this.authorId = ''; this.title = ''; if (this.selectedType == '1'){ this.title = this.selectedItem.category; this.categoryId = this.selectedItem.id; } if (this.selectedType == '2'){ this.title = this.selectedItem.author; this.authorId = this.selectedItem.id; } // // 0 - // 1 - this.loadData(0); } loadData(isNew) { if (isNew==0){ // this.beginElement = 0; this.countElement = 10; // let loadingPopup = this.loadingCtrl.create({ content: '' }); // loadingPopup.present(); // , URL- this.http.get('https://mysite.ru/postlist.php?begin='+this.beginElement+'&limit='+this.countElement+'&c='+this.categoryId+'&a='+this.authorId) .timeout(20000) // 20 . .map(res => res.json()) .subscribe( data => { setTimeout(() => { this.postlists = data.data; // , this.countElement = data.count; // - this.post_error = "0"; // - loadingPopup.dismiss(); // }, 1000); }, err => { loadingPopup.dismiss(); // this.post_error = "1"; // - } ); }else{ // this.beginElement = Number(this.beginElement) + Number(this.countElement); } } // doInfinite(infiniteScroll) { // // 0 , // if (this.countElement != 0){ this.loadData(1); // , URL- this.http.get('https://mysite.ru/postlist.php?begin='+this.beginElement+'&limit='+this.countElement+'&c='+this.categoryId+'&a='+this.authorId) .timeout(20000) .map(res => res.json()) .subscribe( data => { setTimeout(() => { this.postlists_new = data.data; // this.countElement = data.count; this.post_error = "0"; for (let i = 0; i < this.countElement; i++) { this.postlists.push( this.postlists_new[i] ); // } infiniteScroll.complete(); }, 1000); }, err => console.error(err) ); }else{ infiniteScroll.complete(); } } // , doRefresh(refresher) { this.loadData(0); setTimeout(() => { refresher.complete(); }, 2000); } ionViewDidLoad() { console.log('ionViewDidLoad Postlist'); } }
postlist.htmlファイルでは、変更はヘッダー表示部分のみに影響します。
<ion-header> <ion-navbar color="clmain"> <button ion-button menuToggle> <ion-icon name="menu"></ion-icon> </button> <ion-title>{{title}}</ion-title> </ion-navbar> </ion-header>
すべての変更の結果、選択したカテゴリと選択した著者の出版物を表示できるようになりました。
選択したカテゴリと選択した著者の出版物
パブリケーションのコンテンツを表示する最後のページを作成します。すなわち、タイトル、日付、カテゴリ、著者、写真、要約、完全なコンテンツ。
これを行うには、次のコマンドで新しいページを作成します:app.module.ts
ionic generate page post
ファイルに変更を加えます。インポートする行を追加します。
import { Post } from '../pages/post/post';
また、セクション
declarations
とに作成されたページを書き込みます
entryComponents
。
... declarations: [ MyApp, Postlist, Categorylist, Authorlist, TabsPage, Post ], ... entryComponents: [ MyApp, Postlist, Categorylist, Authorlist, TabsPage, Post ], ...
post.tsファイルに、クラス
NavController
とオブジェクトをインポートする行を書きます
NavParams
import { NavController, NavParams } from 'ionic-angular';
さらに、方法論も同様です。リクエストを通じて出版データを取得し、希望する形式で表示します。完成した変更済みファイルの結果:
post.ts
import { Component } from '@angular/core';
import { NavController, NavParams } from 'ionic-angular';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/timeout';
import { LoadingController } from 'ionic-angular';
Component ({
selector: 'page-post',
templateUrl: 'post.html',
})
export class Post {
selectedItem: any;
postphotos: any;
post_category: any;
post_author: any;
post_author_id: any;
post_author_img: any;
post_title: any;
post_dat3: any;
post_intro_text: any;
post_full_text: any;
post_img: any;
post_is_photo: any;
post_error: string;
constructor(public navCtrl: NavController, public http: Http, public loadingCtrl: LoadingController, public navParams: NavParams) {
this.selectedItem = navParams.get('item');
this.loadData();
}
loadData() {
//
let loadingPopup = this.loadingCtrl.create({
content: ''
});
//
loadingPopup.present();
// , URL-
this.http.get('https://mysite.ru/post.php?p='+this.selectedItem.id)
.timeout(20000)
.map(res => res.json())
.subscribe(
data => {
setTimeout(() => {
this.postphotos = data.data;
this.post_category = data.category;
this.post_author = data.author
this.post_author_id = data.author_id;
this.post_author_img = data.author_img;
this.post_title = data.title;
this.post_dat3 = data.dat3;
this.post_intro_text = data.intro_text;
this.post_full_text = data.full_text;
this.post_img = data.img;
this.post_is_photo = data.is_photo;
this.post_error = «0»;
loadingPopup.dismiss();
}, 1000);
},
err => {
loadingPopup.dismiss();
this.post_error = «1»;
}
);
}
// ,
doRefresh(refresher) {
this.loadData();
setTimeout(() => {
refresher.complete();
}, 2000);
}
ionViewDidLoad() {
console.log('ionViewDidLoad Post');
}
}
import { NavController, NavParams } from 'ionic-angular';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/timeout';
import { LoadingController } from 'ionic-angular';
Component ({
selector: 'page-post',
templateUrl: 'post.html',
})
export class Post {
selectedItem: any;
postphotos: any;
post_category: any;
post_author: any;
post_author_id: any;
post_author_img: any;
post_title: any;
post_dat3: any;
post_intro_text: any;
post_full_text: any;
post_img: any;
post_is_photo: any;
post_error: string;
constructor(public navCtrl: NavController, public http: Http, public loadingCtrl: LoadingController, public navParams: NavParams) {
this.selectedItem = navParams.get('item');
this.loadData();
}
loadData() {
//
let loadingPopup = this.loadingCtrl.create({
content: ''
});
//
loadingPopup.present();
// , URL-
this.http.get('https://mysite.ru/post.php?p='+this.selectedItem.id)
.timeout(20000)
.map(res => res.json())
.subscribe(
data => {
setTimeout(() => {
this.postphotos = data.data;
this.post_category = data.category;
this.post_author = data.author
this.post_author_id = data.author_id;
this.post_author_img = data.author_img;
this.post_title = data.title;
this.post_dat3 = data.dat3;
this.post_intro_text = data.intro_text;
this.post_full_text = data.full_text;
this.post_img = data.img;
this.post_is_photo = data.is_photo;
this.post_error = «0»;
loadingPopup.dismiss();
}, 1000);
},
err => {
loadingPopup.dismiss();
this.post_error = «1»;
}
);
}
// ,
doRefresh(refresher) {
this.loadData();
setTimeout(() => {
refresher.complete();
}, 2000);
}
ionViewDidLoad() {
console.log('ionViewDidLoad Post');
}
}
post.html
<ion-header> <ion-navbar color="clmain"> <button ion-button menuToggle> <ion-icon name="menu"></ion-icon> </button> <ion-title></ion-title> </ion-navbar> </ion-header> <ion-content padding> <ion-refresher (ionRefresh)="doRefresh($event)"> <ion-refresher-content pullingIcon="arrow-dropdown" pullingText=" " refreshingSpinner="circles" refreshingText="..."> </ion-refresher-content> </ion-refresher> <div *ngIf="post_error == '0'"> <h3></h3> <div> <div class="post-category">{{post_category}}</div> <div class="post-dat">{{post_dat3}}</div> </div> <h3 class="post-title">{{post_title}}</h3> <img *ngIf="post_is_photo != '1'" src="{{post_img}}" /> <h5 class="post-intro-text">{{post_intro_text}}</h5> <div class="post-text" [innerHTML] = "post_full_text"></div> <button ion-item> <ion-avatar item-left> <img [src]="post_author_img" /> </ion-avatar> <ion-label class="author-title">{{post_author}}</ion-label> </button> </div> <div *ngIf="post_error == '1'" style="text-align: center"> <ion-label> </ion-label> <button ion-button (click)="loadData(0)" color="clmain" icon-left> <ion-icon name="refresh"></ion-icon> </button> </div> </ion-content>
post.scss
page-post { .post-title { font-size: 19px !important; white-space: inherit; } .post-intro-text { font-size: 15px !important; color: gray; white-space: inherit; } .post-dat { font-size: 14px !important; color: gray; white-space: inherit; float: right; text-align: right; width: 50%; } .post-category { font-size: 14px !important; color: gray; white-space: inherit; float: left; width: 50%; } .post-text { font-size: 16px !important; } }
次に、eventのpostlist.htmlで
openPostPage()
呼び出されるメソッドを思い出しましょう。このメソッドは、パブリケーションのコンテンツを含むページを開きます。postlist.tsでメソッドを説明します。
click
openPostPage(item) { this.navCtrl.push(Post, { item: item }); }
また、ページをインポートします
Post
:
import { Post } from '../post/post';
行われたすべての変更の結果を確認し、リスト内の出版物をクリックすると開くページを確認します。
ページコンテンツ
おそらく、パブリケーションをリーフスルーし、そのコンテンツを読み取ることができるすべての基本機能があります。そのデータは、Httpリクエストを介してサイトから取得されます。
このサンプルプロジェクトのソースコードは、GitHubで表示できます。