我在Visual Studio中使用Cordova开发iOS应用程序并且它不断返回此错误:
There is no handler for the following exec call: SQLitePlugin.close({"path":"mobileapps.db"})
我相信在尝试合并在线服务器和本地表时会发生这种情况 . 控制台显示:
OPEN database: mobileapps.db database already open: mobileapps.db new transaction is queued, waiting for open operation to finish
这是我的db.js文件的全部内容(我一直在修改示例todolist Cordova应用程序):
(function () {
"use strict";
var client, // Connection to the Azure Mobile App backend
store, // Sqlite store to use for offline data sync
syncContext, // Offline data sync context
tableName = 'couponCounts',
couponTable; // Reference to a table endpoint on backend
// Set useOfflineSync to true to use tables from local store.
// Set useOfflineSync to false to use tables on the server.
var useOfflineSync = true;
// Add an event listener to call our initialization routine when the host is ready
document.addEventListener('deviceready', onDeviceReady); // false option was enabled before; relevant?
// Event Handler, called when the host is ready
function onDeviceReady() {
console.log("onDeviceReady() called!");
// Create a connection reference to our Azure Mobile Apps backend
client = new WindowsAzure.MobileServiceClient('https://jessica-wants.azurewebsites.net'); // ?ZUMO-API-VERSION=2.0.0
if (useOfflineSync) {
initializeStore().then(setup);
} else {
setup();
}
}
/**
* Set up and initialize the local store.
*/
function initializeStore() {
console.log("initializeStore() running!");
// Create the sqlite store
store = new WindowsAzure.MobileServiceSqliteStore();
// Define the table schema
return store.defineTable({
name: tableName,
columnDefinitions: {
id: 'string', // The coupon
count: 'integer' // The number of that particular coupon remaining
}
}).then(function () {
// Initialize the sync context
syncContext = client.getSyncContext();
// Define an overly simplified push handler that discards
// local changes whenever there is an error or conflict.
// Note that a real world push handler will have to take action according
// to the nature of conflict.
syncContext.pushHandler = {
onConflict: function (pushError) {
return pushError.cancelAndDiscard();
},
onError: function (pushError) {
return pushError.cancelAndDiscard();
}
};
return syncContext.initialize(store);
}, function (error) {
console.error(error);
});
}
/**
* Set up the tables, event handlers and load data from the server
*/
function setup() {
console.log("setup() running!");
// Create a table reference
if (useOfflineSync) {
couponTable = client.getSyncTable(tableName);
} else {
couponTable = client.getTable(tableName);
}
// Cycles over local coupons and ensures that the database contains copies
var coupons = $('.count'), i;
for (i = 0; i < coupons.length; i++) {
var coupon = {
id: coupons[i].id,
count: parseInt(coupons[i].innerText)
};
couponTable
.insert(coupon) // Do something else? Sync w/ online/local? Which one is this?!?!?!
.then(function () {
console.log("Inserted coupon to table! Coupon: ");
console.log(coupon);
});
}
// Refresh the counts
refreshDisplay();
// Adds event handlers
addEventHandlers();
}
function addEventHandlers() {
// Wire up the UI Event Handler
var coupons = document.querySelectorAll("#home button"), counts = $('.count'), i;
for (i = 0; i < coupons.length; i++) {
// Unbinding the click handler first prevents the function from being called twice [.unbind('click')]
$(coupons[i]).click(function () {
redeemCoupon(this.id);
refreshDisplay();
});
$(counts[i]).on('change', function () {
var coupon = this.id;
var newCount = this.text();
updateTable(coupon, newCount);
});
}
}
/**
* Refresh the display with items from the table.
* If offline sync is enabled, the local table will be synchronized
* with the server table before displaying the counts.
*/
function refreshDisplay() {
console.log("refreshDisplay() running!");
if (useOfflineSync) {
syncLocalTable().then(displayCounts);
} else {
displayCounts();
}
}
/**
* Synchronize local table with the table on the server.
* We do this by pushing local changes to the server and then
* pulling the latest changes from the server.
*/
function syncLocalTable() {
console.log("syncLocalTable() running!");
return syncContext
.push()
.then(function () {
return syncContext.pull(new WindowsAzure.Query(tableName));
});
}
/**
* Displays the counts for the various coupons
*/
function displayCounts() {
console.log("displayCounts() running!");
// Execute a query for uncompleted items and process
couponTable
.where({ complete: false }) // Set up the query (?)
.read() // Read the results
.then(applyOnlineCounts, handleError);
}
/**
* Create the DOM for a single coupon
* @param {Object} coupon the coupon
* @param {string} coupon.id the ID of the coupon
* @param {integer} coupon.count the number of that coupon remaining
* @returns {jQuery} jQuery DOM object
*/
var numInRow = 0;
function createCoupon(coupon) {
// Because the old DOM is still loaded at this point, I can just pull the manually typed name.
var couponName = $("button#" + coupon.id).text();
var finalButton = $('<button id="' + coupon.id + '"><span class="overflow">' + couponName + '</span></button>');
console.log(coupon);
if (numInRow == 0) {
// Creates a row
numInRow++;
return $('<div class="row">')
.append($(finalButton));
} else if (numInRow < 3) {
// Adds to the row
numInRow++;
return finalButton;
} else {
// Finishes the row
numInRow = 0;
return $(finalButton)
.append($('</div>'));
}
}
// Applies the counts from the Azure table locally
function applyOnlineCounts(coupons) {
console.log("applyOnlineCounts(coupons) running!");
var couponList = $.map(coupons, createCoupon);
console.log("Coupons (applyOnlineCounts):");
console.log(couponList);
// Cycle through each coupon received from Azure and update the local counts
$('#coupon-display').empty().append(couponList); // .toggle(listItems.length > 0)
// Adds event handlers
addEventHandlers();
}
// Default error handler; just logs to console to hide problems from end user
function handleError(error) {
console.log("handleError():");
var text = error + (error.request ? ' - ' + error.request.status : '');
console.error(text);
}
// Updates the online table after activating the coupon
function updateTable(coupon, newCount) {
console.log("updateTable() running!");
// coupon = ID of coupon redeemed
// newCount = the number of the coupon left
couponTable
.update({ id: coupon, count: newCount }) // Async send the update to backend
.then(function () {
console.log("Updated table! New values: " + coupon + ", " + newCount);
});
}
})();
如果你需要,我可以上传其他文件,但我已经在这个问题上苦苦挣扎数周了 . 任何帮助将不胜感激 .