ionic3基础学习(3):搭建 ionic3 项目框架

1、ionic 创建项目

命令:ionic start 项目名称 [模板]

注:使用 ionic start --list 命令可以查看所有可用模板。

在这里插入图片描述

ionic3 可用模板有:

  • tabs:具有简单选项卡式界面的启动项目。
  • blank:空白启动项目。
  • sidemenu:具有侧菜单的起始项目,该侧菜单在内容区域中具有导航。
  • super:一个初始项目,包含 Ionic 开发的预构建页面、提供程序和最佳实践。
  • conference:演示实际应用程序的项目。
  • tutorial:一个基于教程的项目,与 Ionic 文档一起提供。
  • aws:AWS 移动中心入门版。

Ionic 升级后,新版的 ionic 创建不同版本项目指令如下:

  • ionic1版本:ionic start myApp --type=ionic1
  • ionic2版本:ionic start myApp --type=ionic2
  • ionic3版本:ionic start myApp --type=ionic-angular
  • ionic4版本:ionic start myApp 或 ionic start myApp --type=angular

如创建 ionic3 项目:ionic start 项目名称 --type=ionic-angular

2、ionic3 项目搭建步骤

1. 创建完一个 ionic3 项目后,使用 ionic serve 命令运行项目。

2. 然后执行 ionic cordova platform ls 命令查看可安装/已安装的 platform。

在这里插入图片描述在这里插入图片描述

3. 执行 ionic cordova platform add android@9.1.0 命令,为项目添加指定版本的 android 平台。

在这里插入图片描述

4. 创建一些通用的服务

在这里插入图片描述

(1)app-service: 封装全局变量服务,包括定义全局变量和接口地址。
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';

/*
  Generated class for the AppServiceProvider provider.

  See https://angular.io/guide/dependency-injection for more info on providers
  and Angular DI.
*/
@Injectable()
export class AppGlobal {
  // 缓存 key 的配置
  static cache: any = {
    slides: "_dress_slides",
    categories: "_dress_categories",
    products: "_dress_products"
  }

  // 接口基地址
  static domain = "http://219.140.164.18:8021";//服务器
  // static domain="http://10.42.52.230:8888";
  //   "/prod-api";
  //  "/dev-api";
  // static routes = "/prod-api";//本地
  static routes = "/devModuels-api";//服务器

  // 接口地址
  static API = {
    postLogin: '/prod-api/auth/login',//登录
    getCode: '/prod-api/code',//获取验证
    logout: "/prod-api/auth/logout",//退出登录
    getInfo: "/prod-api/system/user/getInfo",//用户信息

    getTaskDataFill: AppGlobal.routes + "/aquaticBiodiversity/taskDataFill/list",//水生生物多样性监测-任务
    getTaskList: AppGlobal.routes + "/townCheck/app/task/list",//首页地图接口
    getAddLngAndLatLine: AppGlobal.routes + "/townCheck/app/task/addLngAndLatLine",//巡航功能
    postAppUpload: AppGlobal.routes + "/townCheck/app/task/upload",//保存图片经纬度和方向
    getSampleList: AppGlobal.routes + "/aquaticBiodiversity/taskDataFill/getSampleList",//水生生物多样性监测-任务填报 
    postAddTaskData: AppGlobal.routes + "/aquaticBiodiversity/taskDataFill/addTaskData",//水生生物多样性监测-
    putAuditTaskBatch: AppGlobal.routes + "/aquaticBiodiversity/task/management/auditTaskBatch",
    postUploadSurfacePhoto: AppGlobal.routes + "/aquaticBiodiversity/taskDataFill/uploadSurfacePhoto",//县域生态图片上传
    appUploadSurfacePhoto: AppGlobal.routes + "/aquaticBiodiversity/taskDataFill/appUploadSurfacePhoto",
    getCheckTaskList: AppGlobal.routes + "/townCheck/check/task/list",//县域生态环境质量核查
    putCheckTaskSampling: AppGlobal.routes + "/townCheck/app/task/sampling",//开始采样接口
    postAddTcRepresentative: AppGlobal.routes + "/townCheck/app/task/addTcRepresentative",//新增典型地物准确性核查数据
    postAddTcPeriphery: AppGlobal.routes + "/townCheck/app/task/addTcPeriphery",//新增地类边界准确性核查数据
    postAddTcDynamic: AppGlobal.routes + "/townCheck/app/task/addTcDynamic",//新增地物动态变化核查数据
    postAddTcDisaster: AppGlobal.routes + "/townCheck/app/task/addTcDisaster",//新增生态灾害核查数据
    postUpload: AppGlobal.routes + "/townCheck/app/task/upload",//县域生态 图片上传
    getFeatureType: AppGlobal.routes + "/townCheck/app/task/getAllLandType",//地物类型
    getPoinDataAll: AppGlobal.routes + "/verification/app/poinData/findAll",//样地质控-所有点位
    getVideoParams: AppGlobal.routes + "/verification/app/poinData/getVideoParams",//样地质控-获取视频参数
    getAllImage: AppGlobal.routes + "/townCheck/app/task/getAllImage",//地图底图
    getSavePointNumber: AppGlobal.routes + "/verification/app/poinData/savePointNumber",//样地质控-储存样地编码
    postAddSampling: AppGlobal.routes + "/verification/pointSampling/addSampling",//样地质控-暂存、结束采样
    getFindSamplingById: AppGlobal.routes + "/verification/pointSampling/findSamplingById",//样地质控-根据采样id查询采样信息
    postPointSamplingUpload: AppGlobal.routes + "/verification/pointSampling/upload",//样地质控-单图片上传
    postPointSamplingUploads: AppGlobal.routes + "/verification/pointSampling/uploads",//样地质控-多图片上传
    getShowImg: AppGlobal.routes + "/verification/pointSampling/showImg",//样地质控-图片查看
  };

}

@Injectable()
export class AppServiceProvider {
  private static instance: AppServiceProvider = new AppServiceProvider();
  // 当前用户信息
  public userInfo: any = {};
  // 更新地址
  // http://219.140.164.18:8021/hbsApp/version.xml
  public updateUrl: any = AppGlobal.domain + '/hbsApp/version.xml';//更新地址

  public jurisdiction: boolean;
  public timeNum: any = 0;
  public webSocket: WebSocket;// websocket对象
  public videoData: any;
  public videoBoolean: boolean;//是否有权限进房间
  public videoErrorName: any;
  public connectSuccess: boolean;// websocket 连接成功
  public onCloseWebSocket: boolean = true;
  public videoNum: any = 1;

  constructor() {
    console.log('Hello AppServiceProvider Provider');
    if (AppServiceProvider.instance) {
      throw new Error("错误: 请使用AppServiceProvider.getInstance() 代替使用new.");
    }
    AppServiceProvider.instance = this;

  }

  /**
    * 获取应用单例
    * 
    * @static  
    * @returns {AppServiceProvider}
    */
  public static getInstance(): AppServiceProvider {
    return AppServiceProvider.instance;
  }

}

使用: 使用前需要先引入该服务。

  getSiteList() {
    let param: any = {};

    if (AppServiceProvider.getInstance().userInfo.user.belongCity) {
      param.cityName = AppServiceProvider.getInstance().userInfo.user.belongCity;
    }

    this.http.httpGet(
      AppGlobal.domain + AppGlobal.API.getPoinDataAll, param,
      res => {
        this.dataList = res;
        this.checkedNumber = res.filter(item => item.state == 2).length;
        this.uncheckedNumber = res.filter(item => item.state != 2).length;
        this.addMarker(this.dataList);
      },
      error => {
        this.toast(error);
      }, 1, false, true, 1)

  }

(2)http-service: 封装全局网络请求服务

该服务包括:post 请求、 get 请求、 put 请求以及 delete 请求。

import { AppServiceProvider } from '../app-service/app-service';
import { HttpClient, HttpParams } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { LoadingController, Events } from 'ionic-angular';

/*
  Generated class for the HttpServiceProvider provider.

  See https://angular.io/guide/dependency-injection for more info on providers
  and Angular DI.
*/
@Injectable()
export class HttpServiceProvider {

  constructor(public http: HttpClient, public loadingCtrl: LoadingController, public events?: Events) {
    console.log('Hello HttpServiceProvider Provider');
  }

  // 对参数进行编码
  encode(params) {
    var str = '';
    if (params) {
      for (var key in params) {
        if (params.hasOwnProperty(key)) {
          var value = params[key];
          str += encodeURIComponent(key) + '=' + encodeURIComponent(value) + '&';
        }
      }
      if (str) {
        str = '?' + str.substring(0, str.length - 1);

      }

    }
    return str;
  }

  httpPost(api, params, success, failed, loader: boolean = true, token: number = 1, dataJudge: number = 1, paramsBoolean: boolean = true) {
    let headers = this.setHeader(token);
    let loading = this.loadingCtrl.create({
      content: '加载中....',
      spinner: 'crescent',
    });
    if (loader) {
      loading.present();
    }
    setTimeout(() => {
      if (loader) {
        loading.dismiss();
      }
    }, 1000 * 10);
    let httpParams;
    if (paramsBoolean) {
      httpParams = new HttpParams();
      for (const key in params) {
        httpParams = httpParams.set(key, params[key]);
      }
    } else {
      httpParams = params;
    }

    this.http.post(api, httpParams, headers).subscribe(res => {
      setTimeout(() => {
        if (loader) {
          loading.dismiss();
        }
        let data = this.setDataJudge(dataJudge, res)
        if (data.code == 401) {
          this.events.publish("tokenError150", data.msg);
        } else if (data.code == 200) {
          success(data.data);
        } else {
          failed(data.msg)
        }
      }, 500);
    }, error => {
      setTimeout(() => {
        if (loader) {
          loading.dismiss();
        }
        console.log(error);
        console.log(error.code)
        failed(error.msg);
      }, 500);
    });

  }

  httpGet(api, params, success, failed, loader: boolean = true, token: number = 1, dataJudge: number = 1, paramsBoolean: boolean = true) {

    let headers = this.setHeader(token);

    let loading = this.loadingCtrl.create({
      content: '加载中....',
      spinner: 'crescent',
    });
    if (loader) {
      loading.present();
    }
    setTimeout(() => {
      if (loader) {
        loading.dismiss();
      }
    }, 1000 * 10);

    this.http.get(api + (paramsBoolean ? this.encode(params) : params), headers).subscribe(res => {
      setTimeout(() => {
        if (loader) {
          loading.dismiss();
        }
        let data = this.setDataJudge(dataJudge, res)
        if (data.code == 401) {
          this.events.publish("tokenError150", data.msg);
        } else if (data.code == 200) {
          success(data.data);
        } else {
          failed(data.msg)
        }
      }, 500);
    }, error => {
      setTimeout(() => {
        if (loader) {
          loading.dismiss();
        }
        failed(error.msg);
      }, 500);
    });


  }
  login(api, params, success, failed, loader: boolean = true, dataJudge: boolean = true) {
    let headers;


    let loading = this.loadingCtrl.create({
      content: '加载中....',
      spinner: 'crescent',
    });
    if (loader) {
      loading.present();
    }
    setTimeout(() => {
      if (loader) {
        loading.dismiss();
      }
    }, 1000 * 10);
    let httpParams;
    if (dataJudge) {
      httpParams = new HttpParams();
      for (const key in params) {
        httpParams = httpParams.set(key, params[key]);
      }
    } else {
      httpParams = params;
    }


    this.http.post(api, httpParams, headers).subscribe(res => {
      let data = JSON.parse(JSON.stringify(res));
      setTimeout(() => {
        if (loader) {
          loading.dismiss();
        }
        switch (data.code) {
          case 200:
            success(data.data);
            break;
          case 505:
            // this.events.publish("tokenError150", data.msg);
            failed(data.msg);

            break;
          default:
            failed(data.msg);
            break;
        }
      }, 500);
    }, error => {
      setTimeout(() => {
        if (loader) {
          loading.dismiss();
        }
        console.log(error);
        console.log(error.code)
        switch (error.code) {
          case 505:
            // this.events.publish("tokenError150", error.msg);
            failed(error.msg);
            break;
          default:
            failed(error.error.msg);
            break;
        }
      }, 500);
    });

  }
  httpPut(api, params, success, failed, loader: boolean = true, token: number = 1, dataJudge: number = 1, paramsBoolean: boolean = true) {
    let headers = this.setHeader(token);
    let loading = this.loadingCtrl.create({
      content: '加载中....',
      spinner: 'crescent',
    });
    if (loader) {
      loading.present();
    }
    setTimeout(() => {
      if (loader) {
        loading.dismiss();
      }
    }, 1000 * 10);
    let httpParams;
    if (paramsBoolean) {
      httpParams = new HttpParams();
      for (const key in params) {
        httpParams = httpParams.set(key, params[key]);
      }
    } else {
      httpParams = params;
    }



    this.http.put(api, httpParams, headers).subscribe(res => {
      setTimeout(() => {
        if (loader) {
          loading.dismiss();
        }
        let data = this.setDataJudge(dataJudge, res)
        if (data.code == 401) {
          this.events.publish("tokenError150", data.msg);
        } else if (data.code == 200) {
          success(data.data);
        } else {
          failed(data.msg)
        }

      }, 500);
    }, error => {
      setTimeout(() => {
        if (loader) {
          loading.dismiss();
        }
        failed(error.msg);
      }, 500);
    });

  }
  httpDelete(api, params, success, failed, loader: boolean = true, dataJudge: boolean = true, token: boolean = true, contentType: boolean = true) {
    let headers;

    if (token && contentType) {
      headers = {
        headers: {
          'Authorization': 'Bearer ' + AppServiceProvider.getInstance().userInfo.token,
        }
      };
    }
    let loading = this.loadingCtrl.create({
      content: '加载中....',
      spinner: 'crescent',
    });
    if (loader) {
      loading.present();
    }
    setTimeout(() => {
      if (loader) {
        loading.dismiss();
      }
    }, 1000 * 10);


    this.http.delete(api, headers).subscribe(res => {
      let data = JSON.parse(JSON.stringify(res));
      console.log(data)
      setTimeout(() => {
        if (loader) {
          loading.dismiss();
        }
        success(data);
      }, 500);
    }, error => {
      setTimeout(() => {
        if (loader) {
          loading.dismiss();
        }
        console.log(error);
        console.log(error.code)
        switch (error.code) {
          case 505:
            this.events.publish("tokenError150", error.msg);
            break;
          default:
            failed(error.msg);
            break;
        }
      }, 500);
    });


  }
  setHeader(type) {
    switch (type) {
      case 1:
        return {
          headers: {
            'Authorization': 'Bearer ' + AppServiceProvider.getInstance().userInfo.token,
            'Content-Type': 'application/json; charset=UTF-8'
          }
        }
      case 2:
        return {
          headers: {
            'Authorization': 'Bearer ' + AppServiceProvider.getInstance().userInfo.token,
            'Content-Type': 'application/json;'
          }
        }
      case 3:
        return {
          headers: {
            'Authorization': 'Bearer ' + AppServiceProvider.getInstance().userInfo.token,
          }
        }
      default:
        return {}
    }

  }
  setDataJudge(type, res) {
    if (type == 1) {
      let data = JSON.parse(JSON.stringify(res));
      switch (data.code) {
        case 200:
          return {
            code: 200, data: data.data, msg: data.mag
          };
        case 401:
          return {
            code: 401, data: data.data, msg: data.mag
          };
        default:
          return {
            code: data.code, data: data.data, msg: data.msg
          };
      }
    } else if (type == 2) {
      switch (res.code) {
        case 200:
          return {
            code: 200, data: res, msg: res.mag
          };
        case 401:
          return {
            code: 401, data: res, msg: res.mag
          };
        default:
          return {
            code: res.code, data: res, msg: res.msg
          };
      }
    } else if (type == 3) {
      let data = JSON.parse(JSON.stringify(res));
      switch (data.code) {
        case 200:
          return {
            code: 200, data: data.rows, msg: data.mag
          };
        case 401:
          return {
            code: 401, data: data.rows, msg: data.mag
          };
        default:
          return {
            code: data.code, data: data.rows, msg: data.msg
          };
      }
    }
  }
}

(3)native-service: 封装判断是否是android真机环境
import { Platform } from 'ionic-angular';
import { Injectable } from '@angular/core';

/*
  Generated class for the NativeServiceProvider provider.

  See https://angular.io/guide/dependency-injection for more info on providers
  and Angular DI.
*/
@Injectable()
export class NativeServiceProvider {

  constructor(public platform: Platform) {
    console.log('Hello NativeServiceProvider Provider');
  }

  /**
   * 是否是真机环境
   * @returns {boolean}
   * @memberof NativeService
   */
  isMobile(): boolean {
    return this.platform.is("mobile") && !this.platform.is("mobileweb");
  }


  /**
   * 是否android真机环境
   * @returns {boolean}
   * @memberof NativeService
   */
  isAndroid(): boolean {
    return this.isMobile() && this.platform.is("android");
  }

}

(4)storage-service: 封装全局获取/移除缓存数据的服务

先安装 android 和 ios 中变量的原生存储插件 Native Storage

在这里插入图片描述

$ ionic cordova plugin add cordova-plugin-nativestorage
$ npm install --save @ionic-native/native-storage@4
import { Platform } from 'ionic-angular';
import { Injectable } from '@angular/core';
import { NativeStorage } from '@ionic-native/native-storage';

/*
  Generated class for the StorageServiceProvider provider.

  See https://angular.io/guide/dependency-injection for more info on providers
  and Angular DI.
*/
@Injectable()
export class StorageServiceProvider {
  webFlag: boolean;
  
  constructor(public platform: Platform, public storage: NativeStorage) {
    // console.log('Hello StorageServiceProvider Provider');
    if (platform.is("mobileweb")) {
      this.webFlag = true;
    } else if (platform.is("mobile")) {
      this.webFlag = false;
    } else {
      this.webFlag = true;
    }
  }

  getItem(key: string) {
    return new Promise((resolve, reject) => {
      if (this.webFlag) {
        let res = window.localStorage.getItem(key);
        if (res) {
          resolve(JSON.parse(res));
        } else {
          resolve(res);
        }
      } else {
        this.storage.getItem(key).then(res => {
          if (res) {
            resolve(JSON.parse(res));
          } else {
            resolve(res);
          }
        }, error => {
          if (error.code == 2) {
            resolve("");
          } else {
            reject();
          }
        });
      }
    })
  }

  setItem(key: string, value) {
    return new Promise((resolve, reject) => {
      value = JSON.stringify(value);
      if (this.webFlag) {
        window.localStorage.setItem(key, value);
        resolve("");
      } else {
        this.storage.setItem(key, value).then(res => {
          resolve("");
        }, error => {
          reject();
        })
      }
    })
  }

  remove(key: string) {
    return new Promise((resolve, reject) => {
      if (this.webFlag) {
        window.localStorage.removeItem(key);
        resolve("");
      } else {
        this.storage.remove(key).then(res => {
          resolve("");
        }, error => {
          reject();
        });
      }
    })
  }

  clear() {
    return new Promise((resolve, reject) => {
      if (this.webFlag) {
        window.localStorage.clear();
      } else {
        this.storage.clear().then(res => {
          resolve("");
        }, error => {
          reject();
        });
      }
    })
  }

}

(5)utils-service: 封装全局工具类服务
(6)websocket-service: 封装 websocket 服务

参考: ionic 集成 websocket

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
import { interval } from 'rxjs/observable/interval';
import { AppServiceProvider } from '../app-service/app-service';

/*
  Generated class for the WebsocketServiceProvider provider.

  See https://angular.io/guide/dependency-injection for more info on providers
  and Angular DI.
*/
@Injectable()
export class WebsocketServiceProvider {
  messageSubject;                                 // subject对象,用于发送事件
  private url;                                    // 默认请求的url
  // private webSocket: any;                      // websocket对象
  // connectSuccess: any;                         // websocket 连接成功
  period = 60 * 1000 * 10;                        // 10分钟检查一次
  serverTimeoutSubscription = null;               // 定时检测连接对象
  reconnectFlag = false;                          // 重连  true 不重连  false 重连
  reconnectPeriod = 5 * 1000;                     // 重连失败,则5秒钟重连一次
  reconnectSubscription = null;                   // 重连订阅对象
  runTimeSubscription;                            // 记录运行连接subscription
  runTimePeriod = 60 * 10000;                     // 记录运行连接时间
  messageList: any = [];                          // 消息列表


  constructor(public http: HttpClient) {
    console.log('Hello WebsocketServiceProvider Provider');
    this.messageSubject = new Subject();
    // console.log('开始心跳检测');
    // this.webSocket = AppServiceProvider.getInstance().webSocket;
    // this.connectSuccess = AppServiceProvider.getInstance().connectSuccess;
    // 进入程序就进行心跳检测,避免出现开始就连接中断,后续不重连
    this.heartCheckStart();
    this.calcRunTime();
  }

  /**
   * 发送消息
   * @param message 发送消息
   */
  sendMessage(message: any) {
    AppServiceProvider.getInstance().webSocket.send(message);
  }

  /**
   * 创建新连接
   * @param url 要连接的url
   */
  connect(url: string) {
    if (!!url) {
      this.url = url;
    }
    // 创建websocket对象
    this.createWebSocket();
  }

  /**
   * 创建连接
   */
  createWebSocket() {
    // 如果没有建立过连接,才建立连接并且添加时间监听
    console.log(this.url);
    // this.webSocket = new WebSocket(this.url);
    AppServiceProvider.getInstance().webSocket = new WebSocket(this.url);
    // 建立连接成功
    AppServiceProvider.getInstance().webSocket.onopen = (e) => this.onOpen(e);
    // 接收到消息
    AppServiceProvider.getInstance().webSocket.onmessage = (e) => this.onMessage(e);
    // 连接关闭
    AppServiceProvider.getInstance().webSocket.onclose = (e) => this.onClose(e);
    // 异常
    AppServiceProvider.getInstance().webSocket.onerror = (e) => this.onError(e);
  }

  /** 
   * @Description: 关闭链接
   */
  closeWebSocket() {
    AppServiceProvider.getInstance().webSocket.close();
  }


  /**
   * 连接打开
   * @param e 打开事件
   */
  onOpen(e) {
    console.log('websocket 已连接');
    // 设置连接成功
    // this.connectSuccess = true;
    AppServiceProvider.getInstance().connectSuccess = true;
    // 如果是重连中
    if (this.reconnectFlag) {
      // 1.停止重连
      this.stopReconnect();
      // 2.重新开启心跳
      this.heartCheckStart();
      // 3.重新开始计算运行时间
      this.calcRunTime();
    }
  }

  /**
   * 接收到消息
   * @param event 接收消息事件
   */
  onMessage(event) {
    console.log('接收到的消息', event.data);
    // 将接受到的消息发布出去
    const message = JSON.parse(event.data);
    console.log('接收到消息时间', new Date().getTime());
    this.messageList.push(message);
    console.log(this.messageList);

    this.messageSubject.next(message);
  }

  /**
   * 连接关闭
   */
  private onClose(e) {
    console.log('连接关闭', e);
    // this.connectSuccess = false;
    AppServiceProvider.getInstance().connectSuccess = false;
    AppServiceProvider.getInstance().webSocket.close();
    // 关闭时开始重连
    if (AppServiceProvider.getInstance().onCloseWebSocket) {
      this.reconnect();
      this.stopRunTime();
    }
    // throw new Error('webSocket connection closed:)');
  }

  /**
   * 连接异常
   */
  private onError(e) {
    // 出现异常时一定会进onClose,所以只在onClose做一次重连动作
    console.log('连接异常', e);
    // this.connectSuccess = false;
    AppServiceProvider.getInstance().connectSuccess = false;
    // throw new Error('webSocket connection error:)');
  }

  /**
   * 开始重新连接
   */
  reconnect() {
    // 如果已重连,则直接return,避免重复连接
    if (AppServiceProvider.getInstance().connectSuccess) {
      this.stopReconnect();
      console.log('已经连接成功,停止重连');
      return;
    }
    // 如果正在连接中,则直接return,避免产生多个轮训事件
    if (this.reconnectFlag) {
      console.log('正在重连,直接返回');
      return;
    }
    // 开始重连
    this.reconnectFlag = true;
    // 如果没能成功连接,则定时重连
    this.reconnectSubscription = interval(this.reconnectPeriod).subscribe(async (val) => {
      console.log(`重连:${val}`);
      const url = this.url;
      // 重新连接
      this.connect(url);
    });
  }

  /**
   * 停止重连
   */
  stopReconnect() {
    // 连接标识置为false
    this.reconnectFlag = false;
    // 取消订阅
    if (typeof this.reconnectSubscription !== 'undefined' && this.reconnectSubscription != null) {
      this.reconnectSubscription.unsubscribe();
    }
  }

  /**
   * 开始心跳检测
   */
  heartCheckStart() {
    this.serverTimeoutSubscription = interval(this.period).subscribe((val) => {
      // 保持连接状态,重置下
      if (AppServiceProvider.getInstance().webSocket != null && AppServiceProvider.getInstance().webSocket.readyState === 1) {
        console.log(val, '连接状态,发送消息保持连接');
      } else {
        // 停止心跳
        this.heartCheckStop();
        // 开始重连
        this.reconnect();
        console.log('连接已断开,重新连接');
      }
    });
  }

  /**
   * 停止心跳检测
   */
  heartCheckStop() {
    // 取消订阅停止心跳
    if (typeof this.serverTimeoutSubscription !== 'undefined' && this.serverTimeoutSubscription != null) {
      this.serverTimeoutSubscription.unsubscribe();
    }
  }

  /**
   * 开始计算运行时间
   */
  calcRunTime() {
    this.runTimeSubscription = interval(this.runTimePeriod).subscribe(period => {
      console.log('运行时间', `${period}分钟`);
    });
  }

  /**
   * 停止计算运行时间
   */
  stopRunTime() {
    if (typeof this.runTimeSubscription !== 'undefined' && this.runTimeSubscription !== null) {
      this.runTimeSubscription.unsubscribe();
    }
  }

}

使用:首先需要引入该服务,然后在构造函数中定义,接着就可以在函数中使用了。

 import { WebSocketProvider } from '../../providers/web-socket/web-socket';

// 部分代码示例
  constructor(public storage: StorageServiceProvider,
    public nav: Nav,
    public utils: UtilsServiceProvider,
    public http: HttpServiceProvider,
    public events: Events,
    public webSocketProvider: WebSocketProvider) {

  }

  getVideoParams() {
    let userInfo = AppServiceProvider.getInstance().userInfo;
    this.http.httpGet(
      AppGlobal.domain + AppGlobal.API.getVideoParams,
      {}, res => {
        AppServiceProvider.getInstance().videoData = res;
        AppServiceProvider.getInstance().videoData.userId = userInfo.user.userId
        let gatewayIp = res.webSocketUrl;
        gatewayIp = gatewayIp.replace("7700", "7705").replace("https", "wss").replace("http", "ws");
        console.log(gatewayIp);
        let webSocketUrl = gatewayIp + '/webSocket/message/' + userInfo.user.userId;
        this.webSocketProvider.connect(webSocketUrl);
      }, error => {
      }, false, 1
    )
  }

3、ionic3 项目相关文件解析

(1)app.module.ts 文件解析

官方文档参考:https://angular.cn/guide/bootstrapping

// 根模块,告诉ionic如何组装应用
// 引入 ng ionic 系统模块
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 { AboutPage } from '../pages/about/about';
import { ContactPage } from '../pages/contact/contact';
import { HomePage } from '../pages/home/home';
import { TabsPage } from '../pages/tabs/tabs';

// ionic 打包成 app 以后配置启动画面以及导航条的服务
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';

// 引入自定义服务
import { AppServiceProvider } from '../providers/app-service/app-service';
import { HttpServiceProvider } from '../providers/http-service/http-service';
import { NativeServiceProvider } from '../providers/native-service/native-service';
import { StorageServiceProvider } from '../providers/storage-service/storage-service';
import { UtilsServiceProvider } from '../providers/utils-service/utils-service';
import { WebsocketServiceProvider } from '../providers/websocket-service/websocket-service';

@NgModule({
  // 声明要用到的页面
  declarations: [
    MyApp,
    AboutPage,
    ContactPage,
    HomePage,
    TabsPage
  ],
  // 引入的模块 依赖的模块
  imports: [
    BrowserModule,
    IonicModule.forRoot(MyApp, {
      tabsHideOnSubPages: 'true', // 隐藏全部子页面tabs
      backButtonText: '',  // 返回按钮的文本为空
      iconMode: 'ios',// 安卓icon强制使用ios的icon以及样式
      mode: 'ios',// 样式强制使用ios样式
      menuType: 'overlay', // 菜单栏类型为覆盖式菜单
    })
  ],
  // 根组件,启动的模块, angular 创建它并插入到 index.html 宿主页面
  bootstrap: [IonicApp],
  // 配置不会在模块中使用的页面
  entryComponents: [
    MyApp,
    AboutPage,
    ContactPage,
    HomePage,
    TabsPage
  ],
  // 配置服务
  providers: [
    StatusBar,
    SplashScreen,
    { provide: ErrorHandler, useClass: IonicErrorHandler },
    AppServiceProvider,
    HttpServiceProvider,
    NativeServiceProvider,
    StorageServiceProvider,
    UtilsServiceProvider,
    WebsocketServiceProvider
  ]
})
export class AppModule { }

IonicModule.forRoot()是Ionic框架提供的一个静态方法,用于配置Ionic应用程序的全局设置。它是在应用程序的主模块中被调用的。

使用IonicModule.forRoot()方法需要传入一个配置对象作为参数,配置对象中包含了一些属性用于配置应用程序的行为和外观。

以下是一些常用的配置属性和它们的说明:

  • tabsHideOnSubPages: 用于控制是否在子页面中隐藏全部标签页。可选值为’true’或’false’。
  • backButtonText: 设置返回按钮的文本。例如,可以将其设置为空字符串以隐藏返回按钮的文本。
  • iconMode: 设置图标模式,用于指定在不同设备上使用的图标样式。可选值为’ios’或’android’。
  • mode: 设置应用程序的样式模式,用于指定在不同设备上使用的外观样式。可选值为’ios’或’android’。
  • menuType: 设置菜单栏的类型,用于指定菜单的展示方式。可选值为’overlay’、‘push’或’side’。

为了详细了解IonicModule.forRoot()方法的参数配置和使用,请参阅Ionic官方文档。你可以在官方文档的以下网址中找到更多信息:

https://ionicframework.com/docs/angular/config

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值