你好,我在 mainView 中定义了以下函数:
property var db: null
function openDB() {
if(db !== null) return;
// db = LocalStorage.openDatabaseSync(identifier, version, description, estimated_size, callback(db))
db = LocalStorage.openDatabaseSync("pedometer.ubik", "0.1", "Simple example app", 100000);
try {
db.transaction(function(tx){
tx.executeSql('CREATE TABLE IF NOT EXISTS settings(key TEXT UNIQUE, value TEXT)');
var table = tx.executeSql("SELECT * FROM settings");
// Seed the table with default values
if (table.rows.length == 0) {
tx.executeSql('INSERT INTO settings VALUES(?, ?)', ["Stepslength", "0.7"]);
tx.executeSql('INSERT INTO settings VALUES(?, ?)', ["Sensivity", "5.2"]);
console.log('Settings table added');
};
});
} catch (err) {
console.log("Error creating table in database: " + err);
};
}
function saveSetting(key, value) {
openDB();
db.transaction( function(tx){
tx.executeSql('INSERT OR REPLACE INTO settings VALUES(?, ?)', [key, value]);
});
}
function getSetting(key) {
openDB();
var res = "";
db.transaction(function(tx) {
var rs = tx.executeSql('SELECT value FROM settings WHERE key=?;', [key]);
res = rs.rows.item(0).value;
});
return res;
}
saveSetting 函数保存我的设置。getSetting 函数返回一个设置值。
现在我想使用选择器来保存设置:
Picker {
id: pickerStepslength
selectedIndex: parseInt(getSetting("Stepslength")) // this will be set to 0 at the model completion
delegate: PickerDelegate {
Label {
text: modelData
}
}
Component.onCompleted: {
var stack = [];
for (var i = 0; i < 4000; i++) {
stack.push(i / 100.0);
}
model = stack;
// selectedIndex must be set explicitly
selectedIndex = parseInt(getSetting("Stepslength"))
}
onSelectedIndexChanged: {
saveSetting("Stepslength", selectedIndex)
}
}
但它不起作用。它没有将 selectedIndex 保存到我的数据库中。
它应该从数据库中恢复selectedIndex。
我究竟做错了什么?
答案1
我并不是 100% 确定,但我怀疑问题在于你存储了数据库连接,而不是每次需要访问数据库时都重新获取它。LocalStorage 文档说,“在 Javascript 垃圾回收期间,数据库连接会自动关闭。”这让我怀疑连接是否在函数结束时关闭openDB()
,因为它无法识别连接存储在 QML 属性中。
我会将代码改为每次openDB()
调用openDatabaseSync()
时都返回数据库连接给调用者,调用者会将其用作局部变量。这是我经常看到的使用模式。
看起来您的数据库初始化代码得到了妥善保护,但可能有更好的方法。第一种方法是将回调传递给openDatabaseSync()
。仅当数据库刚刚创建并且数据库连接作为参数传递时,才会调用此回调。因此,初始化代码可以在回调中运行。另一种方法是db.version
在获取连接后进行检查。在第一次运行时,这将是空字符串。在以后的运行中,它将被设置为传入 的值openDatabaseSync()
。检查此值对于执行数据库升级也很有用。
例如,你可以查看这个 QML 文件来自我的项目 Beru。