+-
Angluar5+ionic3实践(四)

背景 : 复宏汉霖项目的CR做完了.用时五天.超出预计时间十天.这五天每天都在加班.终于功夫不负有心人.我现在可以开始独自开发Angluar+ionic项目了.之前都是用的React+AntDesign.现在算是扩展了新框架.收获满满.这里最后记录下.这两天开发过程中遇到的问题.学到的知识.

学到的知识:一定会遇到的model弹层
比如这样的需求: 进项目的时候选择岗位,在 我的页面又要有切换岗位的弹框.这时候就会遇到两个点.一个是 model弹层.还有一个就是 抽组件.

image.png

首先来看下抽组件 顾名思义就是把多个用处的同一块东西抽成公共组件.这样在任何页面就可以公用.这也是项目必备技能. 一般都把抽出来的组件放到src/components里面. 来看下我的这个model弹层的公共组件怎么写的: 目录结构:

image.png

代码内容:
choose-job.module.ts 内容:

import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { ChooseJobPage } from './choose-job';
@NgModule({
     declarations: [ChooseJobPage],
     imports: [
        IonicPageModule.forChild(ChooseJobPage),
     ],
})
export class ChooseJobPageModule {}
choose-job.ts 内容:

import { Component, Input } from '@angular/core';
import { NavParams,IonicPage, ViewController } from "ionic-angular";

@IonicPage()
@Component({
 selector: 'choose-job',
 templateUrl: 'choose-job.html',
})
export class ChooseJobPage {
 @Input() jobList: any; // 岗位列表
 checkd = {
    TerritoryID:''
 } // 选中的岗位
 
 // 初始化
 constructor(
     public navParams: NavParams,
     public viewCtrl: ViewController,) {
     this.jobList = this.navParams.get('jobList');
     this.checkd.TerritoryID = this.navParams.get('territoryID') || '';
     }
 // 选中的值
 radioSelected =(v)=>{
    this.checkd = v
 }
 
 // 点击确认
 determine = ()=>{
    this.viewCtrl.dismiss({selectedItem: this.checkd, action: 'save'});
 }
}
choose-job.html 内容:

<ion-header class="modal-header">
     <ion-navbar color="sky" padding-left padding-right>
         <ion-title text-center="">选择岗位</ion-title>
     </ion-navbar>
</ion-header>
<ion-content style="height: 300px;">
     <ion-item-group class="list">
         <ion-item *ngFor="let item of jobList;let i = index" >
             <ion-label>
                 <ion-row>
                 <h3>{{item.TerritoryName}}</h3>
                 <span class="tr">({{item.isPartTime ? "代岗" : "主岗" }})</span>
                 </ion-row>
             </ion-label>
             <ion-radio (click)="radioSelected(item)" [checked]="checkd.TerritoryID === item.TerritoryID" ></ion-radio>
         </ion-item>
         <ion-row justify-content-center align-items-center *ngIf="jobList?.length === 0">
             <img src="assets/icon/no_data.png" alt="" width="70" style="margin-top: 150px"/>
         </ion-row>
     </ion-item-group>
     <button ion-button class="save" (click)="determine()">
        确定
     </button>
</ion-content>
choose-job.scss 内容:

approve-list {
     .list{
         max-height: 200px;
         overflow-x: hidden;
     }
     .tr{
         color: #32a3e7;
         font-size: 12px;
         margin-left: 5px;
     }
     .save{
         width: 87%;
         background: #32a3e7;
         margin: 20px;
         position: absolute;
         bottom: 0;
     }
}
内容解析: 这个公共组件需要的参数只有两个.一个 jobList还有一个 territoryID.( 刚进页面的时候是没有默认值的,在我的里面切换岗位的时候,是需要默认为自己登陆的岗位) 需要注意的地方:

(1): 调用组件是需要在组件页的类上方定义@IonicPage()的.不然获取不到的.
(2): 不加@IonicPage()的组件是被用作标签使用.不需要choose-job.module.ts.在components的公共components.module.ts里面导出就好了.

现在组件抽好了.怎么调用出来呢. 来看下我的页面调用的代码
`我的` html内容:

 <button ion-item (click)="chooseJob()">
     <ion-icon item-start>
         <img src="assets/icon/tr.png" width="30">
     </ion-icon>
     <ion-row>
         <h3>岗位切换</h3>
         <span class="color-blue" style="font-size: 15px;margin-left: 5px;">{{territoryName || ''}}</span>
     </ion-row>
 </button>

`我的` ts内容:

 // 岗位切换
 chooseJob = ()=>{
    // 判断只有一个岗位不触发弹层
     if (this.territoryList.length <= 1) {
        return;
     }
     // 获取岗位id
     let territoryID = localStorage.getItem("territoryID");
     // 获取model弹层 
     // `ChooseJobPage`就是我从`choose-job.module.ts`里面导出的名字.
     // jobList 和 territoryID 就是我给组件的传参
     // cssClass是组件位于页面样式的一个公共css.
     let modal = this.modalCtrl.create("ChooseJobPage", { jobList:this.territoryList ,territoryID},{
     cssClass: 'inset-modal'
     });
     // 点击确定的时候的返回值
     modal.onDidDismiss(data => {
         if (data.action == 'save') {
         // 把新切换的岗位赋值到localStorage里面(用于设置页面展示当前岗位所用)
         this.territoryName = this.territoryList.filter(item => item.TerritoryID === data.selectedItem.TerritoryID)[0].TerritoryName
         }
     });
     modal.present(); 
 }
 `我的` module内容:
 
import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { SetupPage } from './setup';
import {SharedModule} from "../../../app/shared.module";
import { ChooseJobPageModule } from "../../../components/choose-job/choose-job.module"; // 引入组件的module

@NgModule({
 declarations: [],
 imports: [
     IonicPageModule.forChild(SetupPage),
     SharedModule,
     ChooseJobPageModule, // 这里写了ts页面就能取到组件页`ChooseJobPage`了
 ],
})

export class SetupPageModule {}

以上就是model弹层的抽组件和调用,传参的代码了.有想法的可以互相讨论哈.

常用的生命周期
constructor(){} // 初始化
ionViewWillEnter(){
    // 获取页面列表等操作
} //初始化后调用
遇到的需要注意的问题

(1): *ngif*ngfor不可以在同一个标签上使用.可以用div包起来.父上写if子上写for
(2): 给数组列表增加一组数据用array.unshift({key:'',value:''})
(3): 处理日期的方法:
比如date为你要处理的日期

第一种: 利用 moment直接处理 : moment(date).format('YYYYMM').如果是当前年月的话得到的就是 202009.如果需要加 -就是moment(date).format('YYYY-MM').得到的是 2020-09.moment的用法还有很多.感兴趣的可以去官网看看.或者直接 Ctrl点进去看源码.最快最方便. 第二种: 项目是老项目.没有引入 moment也不想装.那就用字符串去处理.参考一下我写的方法
 // 处理年月传参
 getMonth = ()=>{
    // this.date为你把需要处理的日期.用Date转一下.getDate接收.
     let getDate = new Date(this.date)
     // 获取年
     let year = String(getDate.getFullYear());
     // 处理月份(先转为字符串再判断长度不足两位补0)
     let month = String(getDate.getMonth()+1).toString().length > 1 ? String(getDate.getMonth()+1) : '0'+String(getDate.getMonth()+1);
     this.date = year + month;
     // 这时候你页面再调用this.date就是你处理好的日期了.例如得到当前年月就是202009
 }
总结:

从看不懂Angluar+ionic的项目到写完整个复宏汉霖项目的CR.
学到了Angluar+ionic的基本使用.常用的生命周期.echarts处理报表.遇到的问题等等.
让我快速入门了这门框架.相信在不久的将来.Angluar+ionic的项目写的越多就会越顺手.遇到的问题越多就会进步越快.加油.

这个项目的CR一共写了五篇文章.附上之前写的复宏汉霖四篇的链接

复宏汉霖第一篇认识项目(Angular5 + Ionic3 + TS)
Angular5+ionic3实践(一)
Angluar5+ionic3实践(二)
echarts处理报表---Angluar5+ionic3实践(三)