ng-model一次只能从一个Tab保存到webSQL数据库

时间:2015-03-01 11:21:33

标签: angularjs tabs ionic-framework web-sql

我正在使用带有标签界面的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:

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数据库。插入工作,它会像它应该覆盖。但它只保存您所在选项卡中的数据库部分。

E.g。如果我从标签1保存日期,年龄和性别保存。如果我从Tab 2保存日期和细节1,2和3保存。这个用“未定义”覆盖数据的另一部分,甚至想回到另一个标签显示数据仍在字段中。

日期有效的原因是两个标签上都有一个日期选择器绑定到同一个模型 - 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>

2 个答案:

答案 0 :(得分:3)

由于每个选项卡都包含在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>

答案 1 :(得分:0)

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

我对角度及其惯例很新,但有什么阻止你将$rootScope传递给控制器​​,如下所示:
.controller('TabxCtrl', function ($scope, $rootScope) {
两个标签控制器共享此$rootScope

然后你可以使用$rootScope.data来定义在任一选项卡中设置的值,这样当你执行数据库INSERT时,没有任何值是未定义的。

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

我过去使用过jQM,所以我理解你的感受。我在同一条船上想知道这些优势是否超过了新的学习曲线lol 祝好运!