使用 HTML5 WebDatabases 的简单待办事项列表

简介

网络数据库是 HTML5 中的新功能。网络数据库托管在用户的浏览器中并在其中保留。 通过允许开发者创建具有丰富查询功能的应用,我们预计将出现一种全新的 Web 应用,能够在线下和线上运行。

本文中的示例代码演示了如何创建一个非常简单的待办事项管理器。本课程将简要介绍 HTML5 中的一些功能。

前提条件

此示例使用命名空间封装数据库逻辑。

var html5rocks = {};
html5rocks.webdb = {};

异步和事务性

在大多数情况下,您使用 Web 数据库支持时,都将使用异步 API。Asynchronous API 是一个非阻塞系统,因此不会通过返回值获取数据,而是会将数据传递到定义的回调函数。

通过 HTML 支持 Web 数据库是事务性的。无法在事务之外执行 SQL 语句。事务有两种类型:读写事务 (transaction()) 和只读事务 (readTransaction())。请注意,读写事务会锁定整个数据库。

第 1 步:打开数据库

您需要先打开数据库,然后才能访问它。
您需要定义数据库的名称、版本、说明和大小。

html5rocks.webdb.db = null;

html5rocks.webdb.open = function() {
var dbSize = 5 * 1024 * 1024; // 5MB
html5rocks.webdb.db = openDatabase("Todo", "1", "Todo manager", dbSize);
}

html5rocks.webdb.onError = function(tx, e) {
alert("There has been an error: " + e.message);
}

html5rocks.webdb.onSuccess = function(tx, r) {
// re-render the data.
// loadTodoItems is defined in Step 4a
html5rocks.webdb.getAllTodoItems(loadTodoItems);
}

第 2 步:创建表

您只能通过在事务内执行 CREATE TABLE SQL 语句来创建表。

我们定义了一个函数,用于在 body onload 事件中创建表格。如果该表尚不存在,系统将会创建该表。

该表名为“todo”,包含 3 列。

  • ID - 递增的顺序 ID 列
  • todo - 一个文本列,用于显示内容正文
  • added_on - 待办事项的创建时间
html5rocks.webdb.createTable = function() {
var db = html5rocks.webdb.db;
db.transaction(function(tx) {
tx.executeSql("CREATE TABLE IF NOT EXISTS " +
                "todo(ID INTEGER PRIMARY KEY ASC, todo TEXT, added_on DATETIME)", []);
});
}

第 3 步:向表格添加数据

我们正在构建一个待办事项管理器,因此能够将待办事项添加到数据库中非常重要。

创建一个事务,并在事务中执行对 todo 表的 INSERT 操作。

executeSql 接受多个参数,即要执行的 SQL 和用于绑定查询的参数值。

html5rocks.webdb.addTodo = function(todoText) {
var db = html5rocks.webdb.db;
db.transaction(function(tx){
var addedOn = new Date();
tx.executeSql("INSERT INTO todo(todo, added_on) VALUES (?,?)",
    [todoText, addedOn],
    html5rocks.webdb.onSuccess,
    html5rocks.webdb.onError);
});
}

第 4 步:从表中选择数据

现在,数据已存储在数据库中,您需要一个函数来检索数据。在 Chrome 中,Webdatabase 使用标准 SQLite SELECT 查询。

html5rocks.webdb.getAllTodoItems = function(renderFunc) {
var db = html5rocks.webdb.db;
db.transaction(function(tx) {
tx.executeSql("SELECT * FROM todo", [], renderFunc,
    html5rocks.webdb.onError);
});
}

请注意,此示例中使用的所有这些命令都是异步的,因此数据不会从事务或 executeSql 调用返回。系统会将结果传递给成功回调。

第 4a 步。渲染表格中的数据

从表中提取数据后,系统会调用 loadTodoItems 方法。

onSuccess 回调接受两个参数。第一个是查询的事务,第二个是结果集。遍历数据非常简单:

function loadTodoItems(tx, rs) {
var rowOutput = "";
var todoItems = document.getElementById("todoItems");
for (var i=0; i < rs.rows.length; i++) {
rowOutput += renderTodo(rs.rows.item(i));
}

todoItems.innerHTML = rowOutput;
}
function renderTodo(row) {
return "<li>" + row.todo + 
        " [<a href='javascript:void(0);' onclick=\'html5rocks.webdb.deleteTodo(" + 
        row.ID +");\'>Delete</a>]</li>";
}

此方法调用的效果是,将待办事项列表呈现为一个名为“todoItems”的 DOM 元素。

第 5 步:从表中删除数据

html5rocks.webdb.deleteTodo = function(id) {
var db = html5rocks.webdb.db;
db.transaction(function(tx){
tx.executeSql("DELETE FROM todo WHERE ID=?", [id],
    html5rocks.webdb.onSuccess,
    html5rocks.webdb.onError);
});
}

第 6 步:连接所有设备

页面加载时,打开数据库并创建表(如果需要),然后渲染可能已存在于数据库中的所有待办事项。

....
function init() {
html5rocks.webdb.open();
html5rocks.webdb.createTable();
html5rocks.webdb.getAllTodoItems(loadTodoItems);
}
</script>

<body onload="init();">

需要一个用于从 DOM 中提取数据的函数,因此请调用 html5rocks.webdb.addTodo 方法

function addTodo() {
var todo = document.getElementById("todo");
html5rocks.webdb.addTodo(todo.value);
todo.value = "";
}