ng模型一次只从一个Tab保存到webSQL数据库



我使用带有选项卡界面的Ionic。表1有一些基本数据,表2有一些更详细的数据。

我使用的数据库插入如下:

$scope.insert = function(date_in, basic_data1, basic_date2, detail1, detail2, detail3) {
db.transaction(function(tx){
  tx.executeSql("INSERT OR REPLACE INTO 'stats' (date, age, gender, val1, val2, val3) VALUES (?,?,?,?,?,?)", [date_in, basic_data1, basic_date2, detail1, detail2, detail3);
  },function(e){
    $log.log("ERROR: " + e.message);
  });
}

这可以从你所在的选项卡中插入数据

ng-click="insert(currentDate, userage, usergender, user_detail1, user_detail2, user_detail3)" 

以及表单元素:

<label class="item item-input">
        <i class="icon ion-clock"></i> 
        <span class="input-label smalltext"> Age</span>
        <input type="number" ng-model="userage">
      </label>

我正在Chrome开发控制台中查看webSQL数据库。插入可以工作,并且它会像应该的那样进行覆盖。但它只保存您所在选项卡中的DB部分。

例如,如果我从表1中保存日期、年龄和性别。如果我从表2中保存日期和详细信息1、2和3保存。这会用"undefined"覆盖数据的其他部分,即使返回到其他选项卡也会显示数据仍在字段中。

日期有效的原因是两个选项卡上都有一个日期选择器,绑定到同一个模型currentDate。

如何每次都从两个选项卡获取要由我的函数处理的数据?我在使用jQM时从未遇到过这个问题。。。

这是控制器中的代码:

.controller('SettingsCtrl', function($scope, $rootScope, $localstorage, $log, $ionicPopup, $ionicActionSheet, $timeout, $cordovaDatePicker) {
$scope.insert = function(date_in, weight_in, heartrate_in, sysbp_in, diabp_in, neck_in, chest_in, biceps_in, waist_in, forearms_in, thighs_in, calves_in) {
console.log(date_in, weight_in, heartrate_in, sysbp_in, diabp_in, neck_in, chest_in, biceps_in, waist_in, forearms_in, thighs_in, calves_in);
db.transaction(function(tx){
  tx.executeSql("INSERT OR REPLACE INTO 'stats' (date, weight, heartrate, sysbp, diabp, neck, chest, biceps, waist, forearms, thighs, calves) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)", [date_in, weight_in, heartrate_in, sysbp_in, diabp_in, neck_in, chest_in, biceps_in, waist_in, forearms_in, thighs_in, calves_in]);
  console.log("The inserted weight is", weight_in);
  console.log("The inserted date is", date_in);
  console.log("The inserted neck is", neck_in);
  console.log("The inserted chest is", chest_in);
  },function(e){
    $log.log("ERROR: " + e.message);
  });
}
 $scope.data = {};
$scope.select = function(date) {
db.transaction(function(tx){
  tx.executeSql("SELECT date, weight, heartrate, sysbp, diabp, chest, biceps, waist, forearms, thighs, calves FROM stats where date =?", [date, weight, heartrate, sysbp, diabp, chest, biceps, waist, forearms, thighs, calves]);
  console.log("The inserted weight is", y);
  },function(e){
    $log.log("ERROR: " + e.message);
  });       
}
$scope.usergender = $localstorage.get('storeGender');
$scope.userage = parseInt($localstorage.get('storeAge'));
$scope.userheight = parseInt($localstorage.get('storeHeight'));
$scope.userunits = $localstorage.get('storeUnits');
$scope.userdate = $localstorage.get('storeDate');
$scope.useranalytics = $localstorage.get('storeAnalytics');
$scope.changeVal = function(storeName, val){
$localstorage.set(storeName,val);
console.log(storeName + " is now " + val);
}
 // Date converter UK or US //
 Date.prototype.dateConvertUK = function() {
function two(n) {
  return (n < 10 ? '0' : '') + n;
}
return two(this.getDate()) + '/' + two(this.getMonth() + 1) + '/' + this.getFullYear();
};
Date.prototype.dateConvertUS = function() {
function two(n) {
  return (n < 10 ? '0' : '') + n;
}
return two(this.getMonth() + 1) + '/' + two(this.getDate()) + '/' + this.getFullYear();
  };
 var dateTypeUK = true;
// Set todays date
  var d = new Date();
 console.log("New Date is", d);
 if(dateTypeUK===true){
   today = d.dateConvertUK();
    console.log("Today (coverted UK) is", today);
  }else{
   today = d.dateConvertUS();
  console.log("Today (coverted US) is", today);
 } 
 $scope.currentDate = today;
 //Convert date to string
 $scope.dateToString = function(date){
 return date.toString();
} 
var options = {
date: new Date(),
mode: 'date', // or 'time'
minDate: new Date() - 10000,
allowOldDates: true,
allowFutureDates: false,
doneButtonLabel: 'DONE',
doneButtonColor: '#F2F3F4',
cancelButtonLabel: 'CANCEL',
cancelButtonColor: '#000000'
 };
$scope.popupDate = function(){
   console.log("in the popup");
  $cordovaDatePicker.show(options).then(function(date){
     $scope.currentDate = date;
     console.log("processed date is", date);
  });
}   
});

html中的代码是:

<ion-view view-title="Vitals">
<ion-nav-buttons side="secondary">
  <button class="button smalltext" ng-click="popupDate()">
    <i class="icon ion-calendar"></i> {{currentDate}}
  </button>
</ion-nav-buttons>
<ion-content class="padding" has-bouncing="false">
<div class="list">
<label class="item item-input">
    <i class="icon ion-podium"></i>
    <span class="input-label smalltext">Weight (<span id="weightunit">kg</span>)</span>
    <input type="number" ng-model="data.userweight" placeholder="0">kg
  </label>
  <div class="item item-button-right smalltext">
    Your BMI is: high 
    <button class="button button-stable button-clear">
      <i class="icon ion-help-circled"></i>
    </button>
  </div>
</div>
<div class="list">
  <label class="item item-input">
    <i class="icon ion-heart"></i>
    <span class="input-label smalltext">Heart Rate (bpm)</span>
    <input type="number" ng-model="data.userheartrate" placeholder="0">
  </label>
  <div class="item item-button-right smalltext">
    Your Heart Rate is: 
    <button class="button button-stable button-clear">
      <i class="icon ion-help-circled"></i>
    </button>
  </div>
</div>
<div class="list">
  <div class="item item-divider smalltext">
    <i class="icon ion-stats-bars"></i> Blood Pressure
  </div>
  <div class="row">
        <div class="col noPadding">
          <label class="item item-input">
            <i class="icon ion-arrow-up-b"></i>
            <span class="input-label smalltext">Systolic</span>
            <input type="number" placeholder="0" ng-model="data.usersysbp">
          </label>
        </div>
        <div class="col noPadding">
          <label class="item item-input">
            <i class="icon ion-arrow-down-b"></i>
            <span class="input-label smalltext">Diastolic</span>
            <input type="number" placeholder="0" ng-model="data.userdiabp">
          </label>
        </div>    
  </div>          
  <div class="item item-button-right smalltext">
    Your Blood Pressure is: 
    <button class="button button-stable button-clear">
      <i class="icon ion-help-circled"></i>
    </button>
  </div>
</div>
    <button class="button button-mygreen button-full" ng-click="insert(currentDate, data.userweight, data.userheartrate, data.usersysbp, data.userdiabp, data.userneck, data.userchest, data.userbiceps, data.userwaist, data.userforearms, data.userthighs, data.usercalves)">
      <i class="icon ion-android-archive"></i> Save
    </button>
  </ion-content>
</ion-view>

由于每个选项卡都包含在ng-if中,因此每个选项卡都创建了自己的作用域。因此,每个选项卡的作用域上只有它具有输入标记的属性。当您调用insert方法(我假设它是在选项卡的父作用域上创建的)时,只会定义选项卡上的属性

要修复此问题,请在与保存数据的插入函数相同的范围内创建一个对象,并修改选项卡上的输入以引用该数据:

因此,选项卡的父级的控制器是:

.controller('tabmanager', function($scope) {
    $scope.insert = function(date_in, basic_data1, basic_date2, detail1, detail2, detail3) {
         db.transaction(function(tx){
             tx.executeSql("INSERT OR REPLACE INTO 'stats' (date, age, gender, val1, val2, val3) VALUES (?,?,?,?,?,?)", [date_in, basic_data1, basic_date2, detail1, detail2, detail3);
         },function(e){
              $log.log("ERROR: " + e.message);
         });
    }
    $scope.data = {};  //an empty object to hold your model data in this scope
})

您的标记更改为:

<label class="item item-input">
    <i class="icon ion-clock"></i> 
    <span class="input-label smalltext"> Age</span>
    <input type="number" ng-model="data.userage">
</label>
....
....
<button ng-click="insert(data.currentDate, data.userage, data.usergender, data.user_detail1, data.user_detail2, data.user_detail3)">Save</button>

我认为问题基本上是每个选项卡都有自己的数据模型,而在另一个选项卡中定义的数据对此选项卡不可用,所以当您在选项卡2中使用gender时,它是未定义的。

我对angular及其约定还很陌生,但有没有什么可以阻止你将$rootScope传递给控制器,比如这样:
.controller('TabxCtrl', function ($scope, $rootScope) {
并且让两个选项卡控制器共享该$rootScope

然后,您只需使用$rootScope.data来定义在任一选项卡中设置的值,这样在执行数据库INSERT时,就不会有未定义的值。

不确定应用程序的其余部分是如何构建的,但您可以利用
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){ ... })
事件,以确保在离开选项卡之前将最新的字段值保存到$rootScope.data变量中。或者,只要更改或更新了任何字段值,就可以更新$rootScope.data变量。

我过去使用过jQM,所以我理解你的感受。我也在想,优势是否超过了新的学习曲线。哈哈。
祝你好运

最新更新