zoukankan      html  css  js  c++  java
  • 【Ionic+AngularJS 开发】之『个人日常管理』App(二)

    准备工作

    资源

    预装工具

    安装bower

     npm install -g bower
    

     
    安装ngCordova

    bower install ngCordova
    

     
    (*由于网络获取资源的原因,后面几次建项目后都无法下载到,自己便复制了原来的ngCordova目录(到YourProjectwwwwlib目录下),发现也是可以使用的)


    下载好后,在项目的index.hmtl进行引用:

    <script src="lib/ngCordova/dist/ng-cordova.js">
    

    日历工具

    FullCalendar

    安装插件

    本项目需要(安装)的插件有:

    插件名说明扩展阅读
    cordova-plugin-x-toast 消息提示,使用方法如:$cordovaToast.showShortBottom('屏幕下方提示');
    (*仅限平台运行,浏览器调试无效,所以在PC调试时应注意其引起的错误而导致后面代码没执行)
    cordova ionic消息提示
    cordova-sqlite-storage sqlite数据库 cordova调用本地SQLite数据库的方法
    more...
    cordova-plugin-x-socialsharing 内容分享  


    插件的安装基本命令是:

     cordova plugin add XXXX
    

     
    安装好后可在YourProjectwwwwlib目录下看到新增的插件目录,这样就可以在项目中引用了(不用使用<script src="xxx">)。
    在生成platform后,或需再用

    cordova prepare
    

    该命令用以复制文件到平台(并更改一些xml文件的内容)

    概念理解

    service服务

    AngularJS服务是一种单例对象,其主要功能是为实现应用的功能提供数据和对象,通过直接调用服务,可以将复杂的应用功能进行简化或分块化。 按功能的不同,分为内置服务和自定义服务。

    AngularJS提供的常用内置服务有:$scope、$http、$window、$location等


    自定义服务主要包含以下两种:
    1)使用内置的$provide服务
    2)调用模块中的服务注册(如factory、service、constant、value等方法)


    本项目主要采用service来创建服务(service方法与factory不同的是,它可以接收一个构造函数)

    设计与开发

    app.js

      1 angular.module('pdm'
      2     , ['ionic'
      3         , 'ngCordova'
      4     ])
      5     .config(function ($stateProvider, $urlRouterProvider, $ionicConfigProvider) {
      6 
      7         //在android下,tab位置为top,如果想修改其位置在底部,加上下面一句代码:
      8         $ionicConfigProvider.tabs.position('bottom');
      9 
     10         //...
     11 
     12     })
     13     .run(function ($ionicPlatform) {
     14         //...
     15     })
     16 
     17     // 自定义服务:$alertPopup
     18     .service('$alertPopup',
     19     ['$ionicPopup'
     20         , function ($ionicPopup) {
     21         return function (content, title) {
     22             if (title == undefined || title == null)title = '提示';
     23             var alertPopup = $ionicPopup.alert({
     24                 title: title,
     25                 template: content
     26             });
     27 
     28             alertPopup.then(function (res) {
     29                 log('alertPopup.then: ' + res);
     30             });
     31         }
     32     }])
     33 
     34     // 自定义服务:$db
     35     .service('$db', ['$cordovaSQLite', '$alertPopup', '$cordovaToast'
     36         , function ($cordovaSQLite, $alertPopup, $cordovaToast) {
     37             // 初始化数据表
     38             var db = null;
     39             try {
     40                 var _dbName = 'sk';
     41                 if (!(window.cordova && window.SQLitePlugin)) {
     42                     // 创建数据库对象
     43                     db = window.openDatabase(_dbName, '1.0', _dbName, 100 * 1024 * 1024);
     44 
     45                     // web-sql 执行sql方式
     46                     // 首次创建记账表
     47                     db.transaction(
     48                         function (transaction) {
     49                             transaction.executeSql("CREATE TABLE IF NOT EXISTS Finacial_KeepAccount " +
     50                                 "( id integer primary key" +
     51                                 ", account text " +
     52                                 ", SuitType text " +
     53                                 ", ItemText text " +
     54                                 ", MoneyFlowDirect text " +
     55                                 ", Cash REAL " +
     56                                 ", AccountType text " +
     57                                 ", RecordDate text " +
     58                                 ", Remark text" +
     59                                 ")");
     60                         }
     61                     );
     62 
     63                     // 自定义执行sql方式
     64                     // 首次创建日常表
     65                     $cordovaSQLite.execute(db, 'CREATE TABLE IF NOT EXISTS Life_DailyActivity(id integer primary key' +
     66                         ', account text' +
     67                         ', Date text' +
     68                         ', Business text' +
     69                         ', Study text' +
     70                         ', Health text' +
     71                         ', Sport text' +
     72                         ', Others text' +
     73                         ', Remark text' +
     74                         ')');
     75 
     76                 }
     77                 else {
     78                     $alertPopup('fail create ' + _dbName + '.db');
     79                 }
     80             } catch (e) {
     81                 $alertPopup('fail init: ' + e.toString(), '$db Err');
     82             }
     83 
     84             // 内部函数
     85             function db_exec(sql, param, succ_callback, err_callback){
     86                 if (param == undefined || param == null) param = [];
     87                 $cordovaSQLite.execute(db, sql, param)
     88                     .then(function (rst) {
     89                         if (succ_callback == undefined)log('exec: ' + sql);
     90                         else succ_callback(rst);
     91                     }, function (err) {
     92                         if (err_callback == undefined)$alertPopup('exec error: ' + err.message);
     93                         else err_callback(err);
     94                     });
     95             }
     96 
     97             // 外部可调用接口
     98             return {
     99                 // 执行sql
    100                 _exec: function (sql, param, succ_callback, err_callback) {
    101                     db_exec(sql, param, succ_callback, err_callback);
    102                 },
    103                 // 获取数据
    104                 get: function (tbl, cndt, callback) {
    105                     var sql = 'SELECT * FROM ' + tbl + ' WHERE 1=1 ';
    106                     if (cndt != undefined && cndt != '')sql += (' AND ' + cndt);
    107                     db_exec(sql, [],
    108                         function (rst) {
    109                             var data = [];
    110                             for (var i = 0; i < rst.rows.length; i++) data.push(rst.rows.item(i));
    111                             callback(data);
    112                         });
    113                 },
    114                 // 添加
    115                 add: function (tbl, fields, valueArr, silenceExec) {
    116                     var _param = '';
    117                     for (var i = 0; i < fields.split(',').length; i++)_param += ',?';
    118                     _param = _param.substr(1);
    119                     var sql = 'INSERT INTO ' + tbl + '(' + fields + ') values(' + _param + ')';
    120                     db_exec(sql, valueArr,
    121                         function (rst) {
    122                             if (silenceExec == undefined || silenceExec != true)
    123                                 if(!g_debug)
    124                                 $cordovaToast.showShortCenter('add to ' + tbl + ' success');
    125                         });
    126                 },
    127                 // 更新
    128                 update: function (tbl, fields, valueArr, cndt, silenceExec) {
    129                     var fv = '';
    130                     var flds = fields.split(',');
    131                     for (var i = 0; i < flds.length; i++) fv += (', ' + flds[i] + '=? ');
    132                     fv = fv.substr(1);
    133                     var sql = 'UPDATE ' + tbl + ' SET ' + fv + ' WHERE ' + cndt;
    134                     db_exec(sql, valueArr,
    135                         function (rst) {
    136                             if (silenceExec == undefined || silenceExec != true)
    137                                 if(!g_debug)
    138                                 $cordovaToast.showShortCenter('update ' + tbl + ' success');
    139                         });
    140                 },
    141                 // 删除
    142                 delete: function (tbl, cndt, silenceExec) {
    143                     var sql = 'DELETE FROM ' + tbl + ' WHERE ' + cndt;
    144                     db_exec(sql, [],
    145                         function (rst) {
    146                             if (silenceExec == undefined || silenceExec != true)
    147                                 if(!g_debug)
    148                                 $cordovaToast.showShortCenter('delete from ' + tbl + ' success');
    149                         });
    150                 }
    151 
    152             }
    153         }])
    154 
    155 
    156 ;
    View Code

    自定义服务:$alertPopup

    为方便项目内调用,对$ionicPopup进行封装,也方便日后扩展。

    自定义服务:$db

    此$db服务基本就是一个DAL层了,封装了基本的CRUD功能,并根据项目需要做了一些“默认处理”(在程序初始化时,自动创建记账和日常表等)。
    (*这个sqlite文件物理路径很难找,有什么方法可以快速定位,还望知道的园友赐教:))

    记账视图

    HTML部分

     1 <ion-view view-title="DailyKeeper">
     2     <ion-nav-title><b>记账</b></ion-nav-title>
     3     <div class="bar bar-subheader bar-dark">
     4         <h2 class="title">
     5             <a class="button button-icon icon ion-plus-circled" ng-click="showDetail()"></a>
     6         </h2>
     7     </div>
     8 
     9     <ion-content class="has-tabs has-subheader">
    10         <ion-list>
    11             <div ng-repeat="da in dailyAccount">
    12                 <div class="item item-divider" style="display: {{da.ext_displayDivider}}">
    13                     {{da.RecordDate}}
    14                 </div>
    15                 <ion-item class="item-remove-animate item-icon-right"
    16                           type="item-text-wrap" ng-click="showDetail({{da}})" style="color: {{da.ext_TextColor}}">
    17                     【{{da.SuitType}}】{{da.ItemText}}
    18                     <br/>{{da.Cash}}
    19                     <i class="icon ion-chevron-right icon-accessory"></i>
    20 
    21                     <ion-option-button class="button-assertive" ng-click="remove(da)">
    22                         Delete
    23                     </ion-option-button>
    24                 </ion-item>
    25             </div>
    26         </ion-list>
    27     </ion-content>
    28 
    29     <!--弹出内容-->
    30     <script id="detail.html" type="text/ng-template">
    31         <ion-modal-view>
    32             <ion-header-bar>
    33                 <h1 class="title">{{currDA.title}}</h1>
    34                 <button class="button" ng-click="closeDetail()">关闭</button>
    35             </ion-header-bar>
    36             <ion-content>
    37                 <div class="item-input-inset">
    38                     <i class="icon ion-android-calendar"></i>&nbsp;
    39                     <input type="date" ng-model="currDA.RecordDate">
    40                 </div>
    41                 <div class="item item-input-inset">
    42                     <select
    43                             ng-model="currDA.SuitType"
    44                             ng-options="value.SuitType as value.SuitType group by value.MainClass for value in Finacial_SuitClass">
    45                         <option value=""> -账目类型- </option>
    46                     </select>&nbsp;
    47                     <label class="item-input-wrapper">
    48                         <input type="text" ng-model="currDA.ItemText" placeholder="消费项">
    49                     </label>
    50                 </div>
    51                 <div class="item item-input-inset">
    52                     <label class="item-input-wrapper">
    53                         <input type="number" ng-model="currDA.Cash" placeholder="金额">
    54                     </label>&nbsp;
    55                     <label class="toggle">
    56                         <input type="checkbox" ng-model="currDA.Income">
    57                         <div class="track">
    58                             <div class="handle"></div>
    59                         </div>
    60                     </label>(入账)
    61                 </div>
    62                 <div class="item item-input-inset">
    63                     <textarea style=" 100%" ng-model="currDA.Remark" placeholder="备注"></textarea>
    64                 </div>
    65                 <div class="item-input-inset">
    66                     <button class="button button-block button-positive" ng-click="save()">
    67                         Save
    68                     </button>
    69                 </div>
    70             </ion-content>
    71         </ion-modal-view>
    72     </script>
    73 </ion-view>
    View Code

    JavaScript部分

      1 angular.module('pdm')
      2     .controller('Ctrl_DailyKeeper',
      3     ['$scope', '$ionicModal', '$db', '$cordovaToast', '$ionicPopup', '$alertPopup'
      4         , function ($scope, $ionicModal, $db, $cordovaToast, $ionicPopup, $alertPopup) {
      5 
      6         // BLL
      7         $scope.getKA = function (callback, cndt) {
      8             var sql = "SELECT * FROM Finacial_KeepAccount WHERE 1=1 ";
      9             if (cndt != undefined && cndt != '')sql += (' AND ' + cndt);
     10             sql += ' ORDER BY RecordDate desc';
     11             $db._exec(sql, [], function (rst) {
     12                 if (rst.rows.length == 0) {
     13                     if(!g_debug)
     14                     $cordovaToast.showShortCenter('load ka success but no data');
     15                     //return;
     16                 }
     17                 var data = [];
     18                 for (var i = 0; i < rst.rows.length; i++) data.push(rst.rows.item(i));
     19                 callback(data);
     20             });
     21         };
     22         $scope.addKA = function (SuitType, ItemText, MoneyFlowDirect, Cash, AccountType, RecordDate, Remark) {
     23             $db.add('Finacial_KeepAccount'
     24                 , 'SuitType,ItemText,MoneyFlowDirect,Cash,AccountType,RecordDate,Remark, account'
     25                 , [SuitType, ItemText, MoneyFlowDirect, Cash, AccountType, RecordDate, Remark, g_user]);
     26         };
     27         $scope.updateKA = function (id, SuitType, ItemText, MoneyFlowDirect, Cash, AccountType, RecordDate, Remark) {
     28             $db.update('Finacial_KeepAccount'
     29                 , 'SuitType,ItemText,MoneyFlowDirect,Cash,AccountType,RecordDate,Remark'
     30                 , [SuitType, ItemText, MoneyFlowDirect, Cash, AccountType, RecordDate, Remark]
     31                 , 'id=' + id.toString());
     32         };
     33         $scope.deleteKA = function (id) {
     34             $db.delete('Finacial_KeepAccount', 'id=' + id.toString());
     35         };
     36 
     37 
     38         $scope.Finacial_SuitClass = [
     39             {MainClass: '基本生活', SuitType: '餐饮饮食'}
     40             , {MainClass: '基本生活', SuitType: '柴米油盐'}
     41             , {MainClass: '美容化妆', SuitType: '服饰装扮'}
     42             , {MainClass: '收入', SuitType: '福利津贴'}
     43             , {MainClass: '收入', SuitType: '工资'}
     44             , {MainClass: '美容化妆', SuitType: '化妆品美容'}
     45             , {MainClass: '交通通讯', SuitType: '话费网费'}
     46             , {MainClass: '交通通讯', SuitType: '交通费'}
     47             , {MainClass: '人情往来', SuitType: '借出'}
     48             , {MainClass: '投资', SuitType: '理财投资'}
     49             , {MainClass: '文化娱乐', SuitType: '旅游娱乐'}
     50             , {MainClass: '收入', SuitType: '其他收入'}
     51             , {MainClass: '其他支出', SuitType: '其他支出'}
     52             , {MainClass: '人情往来', SuitType: '人际往来'}
     53             , {MainClass: '基本生活', SuitType: '日常用品'}
     54             , {MainClass: '文化娱乐', SuitType: '书报音像'}
     55             , {MainClass: '文化娱乐', SuitType: '数码产品'}
     56             , {MainClass: '基本生活', SuitType: '水果零食'}
     57             , {MainClass: '基本生活', SuitType: '物业水电'}
     58             , {MainClass: '人情往来', SuitType: '孝敬长辈'}
     59             , {MainClass: '基本生活', SuitType: '医药保健'}
     60             , {MainClass: '文化娱乐', SuitType: '运动健身'}
     61         ];
     62         $scope.currDA = {
     63             title: '新增'
     64             , id: 0
     65             , RecordDate: new Date()
     66             , SuitType: ''
     67             , ItemText: ''
     68             , Cash: 0
     69             , Income: false
     70             , Remark: ''
     71         }
     72 
     73         $scope.arrageData = function () {
     74             var _data = $scope.dailyAccount;
     75 
     76             if (_data.length > 0) {
     77                 _data[0].ext_displayDivider = '';
     78 
     79                 if (_data.length > 1) {
     80                     var lastDA = _data[0];
     81                     for (var i = 1; i < _data.length; i++) {
     82                         _data[i].ext_displayDivider = 'none';
     83                         if (new Date(_data[i].RecordDate) < new Date(lastDA.RecordDate)) {
     84                             _data[i].ext_displayDivider = '';
     85                             lastDA = _data[i];
     86                         }
     87                     }
     88                 }
     89             }
     90         };
     91 
     92         $scope.remove = function (da) {
     93             $ionicPopup.confirm({
     94                 title: 'Confrim',
     95                 template: 'Do you really want to delete?',
     96                 scope: $scope,
     97                 buttons: [
     98                     {
     99                         text: '<b>Yes</b>',
    100                         type: 'button-positive',
    101                         onTap: function (e) {
    102                             //$scope.dailyAccount.splice($scope.dailyAccount.indexOf(da), 1);
    103                             $scope.deleteKA(da.id);
    104                             $scope.loadDate();
    105                         }
    106                     },
    107                     {
    108                         type: 'button-canceldark',
    109                         text: '<b>Cancel</b>',
    110                         onTap: function (e) {
    111                             console.log('cancel delete');
    112                         }
    113                     }
    114                 ]
    115             });
    116         };
    117 
    118         $scope.showDetail = function (da) {
    119             if (da == undefined) {
    120                 // 新增
    121                 $scope.currDA.title = '新增';
    122 
    123                 $scope.currDA.id = 0;
    124                 $scope.currDA.RecordDate = new Date();
    125                 $scope.currDA.SuitType = '';
    126                 $scope.currDA.ItemText = '';
    127                 $scope.currDA.Cash = 0;
    128                 $scope.currDA.Income = false;
    129                 $scope.currDA.Remark = '';
    130             } else {
    131                 // 读取
    132                 $scope.currDA.title = '编辑';
    133 
    134                 $scope.getKA(function (data) {
    135                         if (data.length > 0) {
    136                             var item = data[0];
    137 
    138                             $scope.currDA.id = item.id;
    139                             $scope.currDA.RecordDate = new Date(item.RecordDate);
    140                             $scope.currDA.SuitType = item.SuitType;
    141                             $scope.currDA.ItemText = item.ItemText;
    142                             $scope.currDA.Cash = item.Cash;
    143                             $scope.currDA.Income = (item.MoneyFlowDirect == '入账');
    144                             $scope.currDA.Remark = item.Remark;
    145                         }
    146                     }
    147                     , ' id = ' + da.id);
    148             }
    149 
    150             $scope.openModal();
    151         }
    152 
    153         $scope.save = function () {
    154             //log(angular.toJson($scope.currDA));
    155 
    156             if ($scope.currDA.SuitType == ''
    157                 || $scope.currDA.SuitType.indexOf('账目类型') >= 0) {
    158                 $alertPopup('账目类型没有选定哦');
    159                 return;
    160             }
    161 
    162             var _moneyFlowDirection = '出账';
    163             if ($scope.currDA.Income) _moneyFlowDirection = '入账';
    164 
    165             if ($scope.currDA.id == 0) {
    166                 // 新增
    167                 $scope.addKA(
    168                     $scope.currDA.SuitType
    169                     , $scope.currDA.ItemText
    170                     , _moneyFlowDirection
    171                     , $scope.currDA.Cash
    172                     , '我的钱包'
    173                     , dateFormat($scope.currDA.RecordDate, 'ymd')
    174                     , $scope.currDA.Remark
    175                 );
    176                 $scope.closeDetail();
    177                 $scope.loadDate();
    178             }
    179             else {
    180                 // 更新
    181                 $ionicPopup.confirm({
    182                     title: 'Confrim',
    183                     template: 'Do you really want to update?',
    184                     scope: $scope,
    185                     buttons: [
    186                         {
    187                             text: '<b>Yes</b>',
    188                             type: 'button-positive',
    189                             onTap: function (e) {
    190                                 $scope.updateKA(
    191                                     $scope.currDA.id
    192                                     , $scope.currDA.SuitType
    193                                     , $scope.currDA.ItemText
    194                                     , _moneyFlowDirection
    195                                     , $scope.currDA.Cash
    196                                     , '我的钱包'
    197                                     , dateFormat($scope.currDA.RecordDate, 'ymd')
    198                                     , $scope.currDA.Remark
    199                                 );
    200                                 $scope.closeDetail();
    201                                 $scope.loadDate();
    202                             }
    203                         },
    204                         {
    205                             type: 'button-canceldark',
    206                             text: '<b>Cancel</b>',
    207                             onTap: function (e) {
    208                                 console.log('cancel update');
    209                             }
    210                         }
    211                     ]
    212                 });
    213             }
    214         }
    215 
    216         // 弹窗
    217         $ionicModal.fromTemplateUrl('detail.html', {
    218             scope: $scope,
    219             animation: 'slide-in-up'
    220         }).then(function (modal) {
    221             $scope.modal = modal;
    222         });
    223         $scope.openModal = function () {
    224             $scope.modal.show();
    225         };
    226         $scope.closeDetail = function () {
    227             $scope.modal.hide();
    228         }
    229         $scope.$on('$destroy', function () {
    230             $scope.modal.remove();
    231         });
    232 
    233         $scope.loadDate = function () {
    234             $scope.getKA(function (data) {
    235                 for (var i = 0; i < data.length; i++) {
    236                     var _d = data[i];
    237                     _d['ext_displayDivider'] = 'none';
    238                     _d['ext_TextColor'] = 'black';
    239                     if (_d.MoneyFlowDirect == '入账')_d['ext_TextColor'] = 'blue';
    240                 }
    241                 $scope.dailyAccount = data;
    242                 $scope.arrageData();
    243             });
    244         }
    245 
    246         // start
    247         $scope.loadDate();
    248 
    249     }])
    250 ;
    View Code

    说明:

    • arrageData()函数根据(按日期倒序)排序好的数据,设置当日最后一条数据(因为是倒序,所以采用最后一条)的ext_displayDivider属性为none,如此实现在“日期-当日各项收支项”的显示效果——按日分割后来发觉也可以用Ionic的Card,当然也许也有第三方控件可以直接用了。
    • $ionicModal调用的弹窗功能,弹出的是一个完整的页面,本项目为了简便,就直接写在了同页面里“< script id="detail.html" type="text/ng-template">”

    日常视图

    HTML部分

     1 <ion-view view-title="DailyActivity">
     2     <ion-nav-title><b>日常</b></ion-nav-title>
     3     <ion-content class="has-tabs">
     4         <br/>
     5         <div id='calendar'></div>
     6     </ion-content>
     7 
     8     <!--弹出内容-->
     9     <script id="detail.html" type="text/ng-template">
    10         <ion-modal-view>
    11             <ion-header-bar>
    12                 <h1 class="title">活动 / 计划</h1>
    13                 <button class="button" ng-click="closeDetail()">关闭</button>
    14             </ion-header-bar>
    15             <ion-content>
    16                 <div class="item-input-inset">
    17                     <label class="item-input-wrapper">
    18                         <i class="icon ion-android-calendar"></i>&nbsp;
    19                         <span>{{act.tDate}}</span>
    20                     </label>
    21                     &nbsp;
    22                     <span>{{act.id}}</span>
    23                     &nbsp;
    24                     <!--<a class="button button-small" ng-click="save()">Save</a>-->
    25                 </div>
    26                 <div class="list card">
    27                     <div class="item item-divider">
    28                         事务
    29                     </div>
    30                     <div class="item item-body">
    31                         <label class="item-input">
    32                             <textarea style="background-color: whitesmoke" ng-model="act.Business"></textarea>
    33                         </label>
    34                     </div>
    35                     <div class="item item-divider">
    36                         学习
    37                     </div>
    38                     <div class="item item-body">
    39                         <label class="item-input">
    40                             <textarea style="background-color: whitesmoke" ng-model="act.Study"></textarea>
    41                         </label>
    42                     </div>
    43                     <div class="item item-divider">
    44                         健康
    45                     </div>
    46                     <div class="item item-body">
    47                         <label class="item-input">
    48                             <textarea style="background-color: whitesmoke" ng-model="act.Health"></textarea>
    49                         </label>
    50                     </div>
    51                     <div class="item item-divider">
    52                         运动
    53                     </div>
    54                     <div class="item item-body">
    55                         <label class="item-input">
    56                             <textarea style="background-color: whitesmoke" ng-model="act.Sport"></textarea>
    57                         </label>
    58                     </div>
    59                     <div class="item item-divider">
    60                         其他
    61                     </div>
    62                     <div class="item item-body">
    63                         <label class="item-input">
    64                             <textarea style="background-color: whitesmoke" ng-model="act.Others"></textarea>
    65                         </label>
    66                     </div>
    67                 </div>
    68             </ion-content>
    69         </ion-modal-view>
    70     </script>
    71 </ion-view>
    View Code

    JavaScript部分

      1 angular.module('pdm')
      2     .controller('Ctrl_DailyActivity',
      3     ['$scope', '$ionicModal', '$db', '$cordovaToast', '$alertPopup'
      4         , function ($scope, $ionicModal, $db, $cordovaToast, $alertPopup) {
      5 
      6         // BLL
      7         $scope.getDA = function (callback, cndt) {
      8             var sql = "SELECT * FROM Life_DailyActivity WHERE 1=1 ";
      9             if (cndt != undefined && cndt != '')sql += (' AND ' + cndt);
     10             sql += ' ORDER BY Date';
     11             $db._exec(sql, [], function (rst) {
     12                 var data = [];
     13                 for (var i = 0; i < rst.rows.length; i++) data.push(rst.rows.item(i));
     14                 callback(data);
     15             });
     16         };
     17         $scope.addDA = function (Date, Business, Study, Health, Sport, Others, Remark, callback) {
     18             var tbl = 'Life_DailyActivity';
     19             var fields = 'account,Date,Business,Study,Health,Sport,Others,Remark';
     20             var valueArr = [g_user, Date, Business, Study, Health, Sport, Others, Remark];
     21             var _param = '';
     22             for (var i = 0; i < fields.split(',').length; i++)_param += ',?';
     23             _param = _param.substr(1);
     24             var sql = 'INSERT INTO ' + tbl + '(' + fields + ') values(' + _param + ')';
     25             $db._exec(sql, valueArr,
     26                 function (rst) {
     27                     if (callback != undefined && callback != null) callback(rst);
     28                     else $cordovaToast.showShortCenter('add to ' + tbl + ' success');
     29                 });
     30         };
     31         $scope.updateDA = function (Date, Business, Study, Health, Sport, Others, Remark) {
     32             $db.update('Life_DailyActivity'
     33                 , 'Business,Study,Health,Sport,Others,Remark'
     34                 , [Business, Study, Health, Sport, Others, Remark]
     35                 , "Date='" + Date + "'"
     36                 , true);
     37         }
     38 
     39 
     40         $scope.editing = false;
     41         $scope.act = {
     42             id: 0,
     43             tDate: dateFormat(new Date(), 'ymd'),
     44             Business: '',
     45             Study: '',
     46             Health: '',
     47             Sport: '',
     48             Others: '',
     49             Remark: ''
     50         };
     51         var _lastDate = $scope.act.tDate;
     52 
     53         $scope.loadData = function () {
     54             $scope.getDA(function (data) {
     55                     $scope.act.Business = '';
     56                     $scope.act.Study = '';
     57                     $scope.act.Health = '';
     58                     $scope.act.Sport = '';
     59                     $scope.act.Others = '';
     60                     $scope.act.Remark = '';
     61 
     62                     if (data.length > 0) {
     63                         var item = data[0];
     64                         $scope.act.id = item.id;
     65                         $scope.act.Business = item.Business;
     66                         $scope.act.Study = item.Study;
     67                         $scope.act.Health = item.Health;
     68                         $scope.act.Sport = item.Sport;
     69                         $scope.act.Others = item.Others;
     70                         $scope.act.Remark = item.Remark;
     71 
     72                         if ($scope.act.id > 0) {
     73                             $db._exec("delete from Life_DailyActivity where Date='" + $scope.act.tDate + "' and id!=" + $scope.act.id);
     74                         }
     75                     } else {
     76                         $scope.addDA($scope.act.tDate
     77                             , $scope.act.Business
     78                             , $scope.act.Study
     79                             , $scope.act.Health
     80                             , $scope.act.Sport
     81                             , $scope.act.Others
     82                             , $scope.act.Remark
     83                             , function (rst) {
     84                                 $scope.act.id = rst.insertId;
     85                             }
     86                         );
     87                     }
     88                 },
     89                 "Date='" + $scope.act.tDate + "'");
     90         }
     91 
     92         $scope.save = function () {
     93             $scope.updateDA($scope.act.tDate
     94                 , $scope.act.Business
     95                 , $scope.act.Study
     96                 , $scope.act.Health
     97                 , $scope.act.Sport
     98                 , $scope.act.Others
     99                 , $scope.act.Remark
    100             );
    101         }
    102 
    103         // 监听数据变化
    104         $scope.$watch('act.Business', function (newValue, oldValue, scope) {
    105             if ($scope.editing && newValue != oldValue)$scope.save();
    106         });
    107         $scope.$watch('act.Study', function (newValue, oldValue, scope) {
    108             if ($scope.editing && newValue != oldValue)$scope.save();
    109         });
    110         $scope.$watch('act.Health', function (newValue, oldValue, scope) {
    111             if ($scope.editing && newValue != oldValue)$scope.save();
    112         });
    113         $scope.$watch('act.Sport', function (newValue, oldValue, scope) {
    114             if ($scope.editing && newValue != oldValue)$scope.save();
    115         });
    116         $scope.$watch('act.Others', function (newValue, oldValue, scope) {
    117             if ($scope.editing && newValue != oldValue)$scope.save();
    118         });
    119 
    120 
    121         $scope.initData = function () {
    122             var events_data = [];
    123 
    124             // 日常
    125             $scope.getDA(function (data) {
    126                 var op = [];
    127                 op['Business'] = '#387EF5';
    128                 op['Study'] = '#FFC900';
    129                 op['Health'] = '#EF473A';
    130                 op['Sport'] = '#33CD5F';
    131                 op['Others'] = '#B2B2B2';
    132 
    133                 for (var i = 0; i < data.length; i++) {
    134                     var dd = data[i];
    135                     for (var k in op) {
    136                         if (dd[k.toString()] != undefined && dd[k.toString()] != '') {
    137                             var item = [];
    138                             item['color'] = op[k];
    139                             item['title'] = dd[k.toString()].replace('
    ','|').substring(0, 10);
    140                             item['start'] = new Date(dd['Date']);
    141                             events_data.push(item);
    142                         }
    143                     }
    144                 }
    145 
    146                 $('#calendar').fullCalendar('destroy');
    147                 $('#calendar').fullCalendar({
    148                     header: {
    149                         left: 'prev,next today',
    150                         center: 'title',
    151                         right: 'month'//,agendaWeek,agendaDay'
    152                     },
    153                     firstDay: 1,
    154                     events: events_data,
    155                     // 点击空白
    156                     dayClick: function (date, allDay, jsEvent, view) {
    157                         var selDate = $.fullCalendar.formatDate(date, 'yyyy-MM-dd');//格式化日期
    158                         $scope.act.tDate = selDate;
    159 
    160                         $scope.loadData();
    161                         $scope.openModal();
    162                     },
    163                     //单击事件项时触发
    164                     eventClick: function (calEvent, jsEvent, view) {
    165                         $scope.act.tDate = dateFormat(calEvent.start,'ymd');
    166 
    167                         $scope.loadData();
    168                         $scope.openModal();
    169                     }
    170                 });
    171             });
    172         }
    173 
    174 
    175         // 弹窗
    176         $ionicModal.fromTemplateUrl('detail.html', {
    177             scope: $scope,
    178             animation: 'slide-in-up'
    179         }).then(function (modal) {
    180             $scope.modal = modal;
    181         });
    182         $scope.openModal = function () {
    183             $scope.modal.show();
    184 
    185             $scope.editing = true;
    186         };
    187         $scope.closeDetail = function () {
    188             $scope.initData();
    189             $scope.editing = false;
    190 
    191             $scope.modal.hide();
    192         }
    193         $scope.$on('$destroy', function () {
    194             $scope.modal.remove();
    195         });
    196 
    197         // start
    198         $scope.initData();
    199 
    200     }])
    201 ;
    View Code

    说明:

    • 日常数据的录入,采用了“即变即更新”的模式,这里使用$watch函数来监听数据变化。同时为了数据更新功能的便利性,在用户点击某一日弹框时,自动判断当日数据是否存在,不存在则插入空数据。

    打包发布

    生成Android平台安装包

    使用命令:

    cordova platform add android
    cordova build android
    

     (*注意,如果以上步骤出错,常见原因有:

    • 安装的Android SDK和打包的SDK版本不对,下载相应SDK
    • 环境变量没有配置好
    • 安装最新node.js

    *附录

    【源码文件】

    【APK文件】

  • 相关阅读:
    线性代数复习向量空间线性相关向量组的秩
    证明:将n(n为2的幂)个点的位反转环划分为长为j(2的幂)的连续片段,这些片段都是次序等价的(分布式算法)
    vim命令小合集
    poj2240floyd算法
    visual studio打开文件所在目录
    5个0,4个1组成的字符串中,出现01或10的次数为4的不同字符串个数
    max spacing kclustering(类似kruskal最小生成树)并查集Debuging
    算法导论16.35huffman树的表示
    最优二叉查找树optimalBSTC++实现2
    算法导论16.37
  • 原文地址:https://www.cnblogs.com/glife/p/PDM2.html
Copyright © 2011-2022 走看看