-- 第七课:重用组件

听说你喜欢app,那么我就在你的app里面放一个app好了。目前为止我们的应用有三个标签页了,我们现在要加个全新的标签页了。我们本书的第一个应用QuickList跟咱们应用很搭调呢。外出露营的时候Checklist非常方便的说。 我们这节课要做的是基上就是将Quick List功能“拖放”到当前应用中。在Ionic 2和Angular 2 的模块化的天性之下,这些事情可以很轻易的实现。如果你之前已经创建好了Quick List的话,你只要去其中拷贝代码即可,如果没有的话,那么去下载的包里拷贝代码。 没有像“拖放”那么容易,因为直接拖放的话会有一些冲突,但是还是很直白。我们先从文件拷贝开始。 > 拷贝 QuickList 的 models 文件夹到 CamperMate 的 src 文件夹中 > 拷贝 QuickLists 的 checklist 页文件夹到 CamperMate的 pages 文件夹 这两部非常简单,但是现在我们会遇上一点小问题。我们也想要从QuickLists中拷贝HomePage,但是我们的CamperMate已经有HomePage了,所以我们需要做一点点变通。 > 在CamperMate 的 pages 文件夹内创建一个新的文件夹名为 quicklistshome > 将 QuickLists 的 home文件夹里面的内容(home.ts,home.scss,home.html)拷贝到刚才新建的 quicklistshome 里面 > 将 home.ts,home.scss,home.html重命名为quicklistshome.ts,quicklistshome.scss, quicklistshome.html 现在得到的结果是我们从QuickLists中将他的整个home页都拷贝过来了,但是拷贝过来之后我们都重命名为quicklistshome,因为我们不想让他和已有的home页有冲突。如果对上面的内容感觉比较迷惑,那么请查看本书源代码的文件夹结构。 由于我们对文件名进行了变更,我们也需要对代码进行一些变动。我们需要将QuickLists Home Page的类名,同时我们也要修改模板的名字: > 对 src/pages/quicklistshome/quicklistshome.ts 进行如下变更:

import { Component } from '@angular/core';
import { NavController, AlertController, Platform } from 'ionic-angular';
import { ChecklistPage } from '../checklist/checklist';
import { ChecklistModel } from '../../models/checklist-model';
import { Keyboard } from 'ionic-native';
import { Data } from '../../providers/data';

@Component({
    selector: 'page-quicklistshome',
    templateUrl: 'quicklistshome.html'
})
export class QuickListsHomePage {
    checklists: ChecklistModel[] = [];
    local: Storage;

    constructor(public nav: NavController, public platform: Platform, public dataService: Data, public alertCtrl: AlertController) {
    }

    ionViewDidLoad(){
    this.platform.ready().then(() => {
        this.dataService.getData().then((checklists) => {
            let savedChecklists: any = false;

            if(checklists && typeof(checklists) != "undefined"){
                savedChecklists = JSON.parse(checklists);
            }

            if(savedChecklists){
                savedChecklists.forEach((savedChecklist) => {
                    let loadChecklist = new ChecklistModel(savedChecklist.title, savedChecklist.items);
                    this.checklists.push(loadChecklist);

                    loadChecklist.checklist.subscribe(update => {
                        this.save();
                    });
                });
            }
        });
        });
    }
}

注意类型和templateUrl都变了。有一个我们忽略了的事情是我们没有将Quicklists应用的Data服务拷贝过来。这个因为我们的CamperMate应用已经有一个了,所以我们只要对他进行改动就可以了。 > 给 src/providers/data.ts 添加下面两个函数:

getData(): Promise<any> {
    return this.storage.get('checklists');
}

save(data: any): void {
    let saveData = [];
    //Remove observables
    data.forEach((checklist) => {
        saveData.push({
            title: checklist.title,
            items: checklist.items
        });
    });
    let newData = JSON.stringify(saveData);
    this.storage.set('checklists', newData);
}

这两个函数的命名方式和data.ts里面其他函数的命名方式不一样,保持这样的原因是避免对Quicklists功能做更多的修改。 样式方面没有多少要做的,但是我们的Quicklists应用的navbar都是用的secondary颜色,但是CamperMate用的是primary,所以我们需要对它进行改动。 > 修改 src/pages/checklist/checklist.html 的navbar为如下:

<ion-navbar color="primary">

> 修改 src/pages/quicklistshome/quicklistshome.html 的navbar为如下:

<ion-navbar color="primary">

> 修改 src/pages/quicklistshome/quicklistshome.scss 为如下:

page-quicklistshome {
    ion-item-sliding {
        margin: 5px;
    } 

    .home-item {
        font-size: 1.2em;
        font-weight: bold;
        color: #282828;
        padding-top: 10px;
        padding-bottom: 10px;
    } 

    .secondary-detail {
        display: block;
        color: #cecece;
        font-weight: 400;
        margin-top: 10px;
    }
}

button {
    border: none !important;
}

这样一来,我们就在CamperMate应用里面完美移植了QuickLists功能了。我们现在只要加上对于的标签栏就可以了。 > 修改 src/pages/home/home.html以包含下面第四个标签栏

<ion-tabs>
<ion-tab [root]="tab1Root" tabTitle="Location" tabIcon="navigate"></ion-tab>
<ion-tab [root]="tab2Root" tabTitle="My Details" tabIcon="person"></ion-tab>
<ion-tab [root]="tab3Root" tabTitle="Camp Details" tabIcon="bookmarks"></ion-tab>
<ion-tab [root]="tab4Root" tabTitle="Checklists" tabIcon="checkbox"></ion-tab>
</ion-tabs>

这样我们就可以去类定义中定义tab4Root了。 > 修改 src/pages/home/home.ts到如下:

import { Component } from '@angular/core';
import { LocationPage } from '../location/location';
import { MyDetailsPage } from '../my-details/my-details';
import { CampDetailsPage } from '../camp-details/camp-details';
import { QuickListsHomePage } from '../quicklistshome/quicklistshome';

@Component({
    selector: 'page-home',
    templateUrl: 'home.html'
})
export class HomePage {

    tab1Root: any = LocationPage;
    tab2Root: any = MyDetailsPage;
    tab3Root: any = CampDetailsPage;
    tab4Root: any = QuickListsHomePage;

    constructor(){

    }
}

新加的页面也需要去app.module.ts中进行导入。 > 修改src/app/app.module.ts 为如下:

import { NgModule } from '@angular/core';
import { IonicApp, IonicModule } from 'ionic-angular';
import { MyApp } from './app.component';
import { Storage } from '@ionic/storage';
import { HomePage } from '../pages/home/home';
import { LocationPage } from '../pages/location/location';
import { MyDetailsPage } from '../pages/my-details/my-details';
import { CampDetailsPage } from '../pages/camp-details/camp-details';
import { QuickListsHomePage } from '../pages/quicklistshome/quicklistshome';
import { ChecklistPage } from '../pages/checklist/checklist';
import { GoogleMaps } from '../providers/google-maps';
import { Connectivity } from '../providers/connectivity';
import { Data } from '../providers/data';

@NgModule({
    declarations: [
        MyApp,
        HomePage,
        LocationPage,
        MyDetailsPage,
        CampDetailsPage,
        QuickListsHomePage,
        ChecklistPage
    ],
    imports: [
        IonicModule.forRoot(MyApp)
    ],
    bootstrap: [IonicApp],
    entryComponents: [
        MyApp,
        HomePage,
        LocationPage,
        MyDetailsPage,
        CampDetailsPage,
        QuickListsHomePage,
        ChecklistPage
    ],
    providers: [Storage, Data, GoogleMaps, Connectivity]
})
export class AppModule {}

如你所见,这样模组是项目结构使得重用其他应用中的代码非常简单,如果用同名组件的话就会更简单了。 我们的应用现在看起来已经很好了,但是下节课我们要加入一点样式让他更好看些。

Last updated