我使用带有选项卡界面的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,所以我理解你的感受。我也在想,优势是否超过了新的学习曲线。哈哈。
祝你好运