HTML5 Indexed DB入門導(dǎo)學(xué)2
譯文在本系列教程的第一篇http://developer.51cto.com/art/201310/412224.htm 中,我們向大家介紹了IndexedDB的基本知識(shí),在本篇教程中,將繼續(xù)向大家介紹如何使用IndexedDB進(jìn)行CRUD(增刪改查)的功能,其中將特別將講解IndexedDB的更新和刪除功能,并且將會(huì)演示一個(gè)實(shí)際的例子,這個(gè)例子在第三篇教程中將會(huì)用到。
更新記錄
首先看下如何在IndexedDB中更新記錄。如果記得上一篇教程的話,增加數(shù)據(jù)是很簡(jiǎn)單的,如下:
- //定義person
- var person = {
- name:name,
- email:email,
- created:new Date()
- }
- // 定義增加操作
- var request = store.add(person);
對(duì)于更新操作,如果已經(jīng)在對(duì)象中已經(jīng)定義了id作為key,則只需要使用put方法代替add方法即可,代碼如下:
- var person = {
- name:name,
- email:email,
- created:new Date(),
- id:someId
- }
- var request = store.put(person);
和增加的方法一樣,可以指定各類回調(diào)方法對(duì)結(jié)果進(jìn)行異步處理。
刪除記錄
刪除記錄的方法是通過(guò)delete這個(gè)API去實(shí)現(xiàn),下面是例子:
- var t = db.transaction(["people"], "readwrite");
- var request = t.objectStore("people").delete(thisId);
同樣,可以指定各類回調(diào)方法對(duì)結(jié)果進(jìn)行異步處理。
在學(xué)會(huì)了如何使用IndexedDB進(jìn)行CRUD后,下面我們以一個(gè)實(shí)際的例子來(lái)設(shè)計(jì)一個(gè)簡(jiǎn)單的記事本應(yīng)用?!?/p>
記事本應(yīng)用
下面我們來(lái)學(xué)習(xí)如何使用學(xué)到的IndexedDB知識(shí),設(shè)計(jì)一個(gè)簡(jiǎn)單的記事本應(yīng)用。在應(yīng)用啟動(dòng)的時(shí)候,先初始化IndexedDB數(shù)據(jù)庫(kù),并且展示一個(gè)空的表格,能讓用戶增加空的記錄。界面如下圖:
當(dāng)先“Add Note”按鈕后,出現(xiàn)的界面如下圖:
可以在這里輸入要記錄的事情,然后點(diǎn)Save鍵保存。保存后的列表界面如下圖:
#p#
同時(shí)用戶可以再次編輯或刪除記事的內(nèi)容。下面我們首先開始設(shè)計(jì)第一個(gè)頁(yè)面,注意我們使用的是bootstrap框架。
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Note Database</title>
- <link href="bootstrap/css/bootstrap.css" rel="stylesheet">
- <link href="css/app.css" rel="stylesheet">
- </head>
- <body>
- <div class="navbar navbar-inverse navbar-fixed-top">
- <div class="container">
- <div class="navbar-header">
- <a class="navbar-brand" href="#">Note Database</a>
- </div>
- </div>
- </div>
- <div class="container">
- <div id="noteList"></div>
- <div class="pull-right"><button id="addNoteButton" class="btn btn-success">Add Note</button></div>
- <div id="noteDetail"></div>
- <div id="noteForm">
- <h2>Edit Note</h2>
- <form role="form" class="form-horizontal">
- <input type="hidden" id="key">
- <div class="form-group">
- <label for="title" class="col-lg-2 control-label">Title</label>
- <div class="col-lg-10">
- <input type="text" id="title" required class="form-control">
- </div>
- </div>
- <div class="form-group">
- <label for="body" class="col-lg-2 control-label">Body</label>
- <div class="col-lg-10">
- <textarea id="body" required class="form-control"></textarea>
- </div>
- </div>
- <div class="form-group">
- <div class="col-lg-offset-2 col-lg-10">
- <button id="saveNoteButton" class="btn btn-default">Save Note</button>
- </div>
- </div>
- </form>
- </div>
- </div>
- <script src="js/jquery-2.0.0.min.js"></script>
- <script src="bootstrap/js/bootstrap.min.js"></script>
- <script src="js/app.js"></script>
- </body>
- </html>
接下來(lái)是編寫核心的js文件,首先是一個(gè)處理日期的工具類,比較簡(jiǎn)單:
- /* global console,$,document,window,alert */
- var db;
- function dtFormat(input) {
- if(!input) return "";
- var res = (input.getMonth()+1) + "/" + input.getDate() + "/" + input.getFullYear() + " ";
- var hour = input.getHours();
- var ampm = "AM";
- if(hour === 12) ampm = "PM";
- if(hour > 12){
- hour-=12;
- ampm = "PM";
- }
- var minute = input.getMinutes()+1;
- if(minute < 10) minute = "0" + minute;
- res += hour + ":" + minute + " " + ampm;
- return res;
- }
接下來(lái)的代碼中,要首先檢查瀏覽器是否支持IndexedDB,如果支持IndexedDB,則打開數(shù)據(jù)庫(kù),代碼如下:
- $(document).ready(function() {
- if(!("indexedDB" in window)) {
- alert("IndexedDB support required for this demo!");
- return;
- }
- var $noteDetail = $("#noteDetail");
- var $noteForm = $("#noteForm");
- var openRequest = window.indexedDB.open("nettuts_notes_1",1);
- openRequest.onerror = function(e) {
- console.log("Error opening db");
- console.dir(e);
- };
- openRequest.onupgradeneeded = function(e) {
- var thisDb = e.target.result;
- var objectStore;
- //創(chuàng)建記錄
- if(!thisDb.objectStoreNames.contains("note")) {
- console.log("I need to make the note objectstore");
- objectStore = thisDb.createObjectStore("note", { keyPath: "id", autoIncrement:true });
- }
- };
- openRequest.onsuccess = function(e) {
- db = e.target.result;
- db.onerror = function(event) {
- //處理所有的數(shù)據(jù)異常
- alert("Database error: " + event.target.errorCode);
- console.dir(event.target);
- };
- displayNotes();
- };
#p#
在上面的代碼中,首先判斷用戶的瀏覽器是否支持IndexedDB,如果支持的話,則打開數(shù)據(jù)庫(kù),在其中的onupgradeneeded事件中建立名為note的objectstore,并且注意這里要編寫對(duì)應(yīng)的操作成功和失敗的回調(diào)處理事件。一切準(zhǔn)備就緒后,則可以調(diào)用displayNotes()方法顯示所有的記事列表,其代碼如下:
- function displayNotes() {
- var transaction = db.transaction(["note"], "readonly");
- var content="<table class='table table-bordered table-striped'><thead><tr><th>Title</th><th>Updated</th><th>&nbsp;</td></thead><tbody>";
- transaction.oncomplete = function(event) {
- $("#noteList").html(content);
- };
- var handleResult = function(event) {
- var cursor = event.target.result;
- if (cursor) {
- content += "<tr data-key=\""+cursor.key+"\"><td class=\"notetitle\">"+cursor.value.title+"</td>";
- content += "<td>"+dtFormat(cursor.value.updated)+"</td>";
- content += "<td><a class=\"btn btn-primary edit\">Edit</a> <a class=\"btn btn-danger delete\">Delete</a></td>";
- content +="</tr>";
- cursor.continue();
- }
- else {
- content += "</tbody></table>";
- }
- };
- var objectStore = transaction.objectStore("note");
- objectStore.openCursor().onsuccess = handleResult;
- }
在本系列教程的第一篇中,已經(jīng)討論過(guò)如何循環(huán)讀取IndexedDB中的數(shù)據(jù)(使用的是游標(biāo) cursor,還記得么?),但在上面的這段代碼中,我們?cè)趏bjectStore.openCursor()事件的onsuccess方法中,指定了其回調(diào)處理代碼為handleResult,而在handleResult方法中,完成了對(duì)數(shù)據(jù)庫(kù)中數(shù)據(jù)的循環(huán)讀取列表。而在IndexedDB中允許直接在最頂層的事務(wù)中綁定onComplete事件,這就給我們帶來(lái)了方便,比如例子中可以將比如大量的文本輸出(這里的content)交給前端jQuery進(jìn)行顯示處理。
接下來(lái)看刪除,編輯和增加記事的功能代碼:
- $("#noteList").on("click", "a.delete", function(e) {
- var thisId = $(this).parent().parent().data("key");
- var t = db.transaction(["note"], "readwrite");
- var request = t.objectStore("note").delete(thisId);
- t.oncomplete = function(event) {
- displayNotes();
- $noteDetail.hide();
- $noteForm.hide();
- };
- return false;
- });
- $("#noteList").on("click", "a.edit", function(e) {
- var thisId = $(this).parent().parent().data("key");
- var request = db.transaction(["note"], "readwrite")
- .objectStore("note")
- .get(thisId);
- request.onsuccess = function(event) {
- var note = request.result;
- $("#key").val(note.id);
- $("#title").val(note.title);
- $("#body").val(note.body);
- $noteDetail.hide();
- $noteForm.show();
- };
- return false;
- });
- $("#noteList").on("click", "td", function() {
- var thisId = $(this).parent().data("key");
- var transaction = db.transaction(["note"]);
- var objectStore = transaction.objectStore("note");
- var request = objectStore.get(thisId);
- request.onsuccess = function(event) {
- var note = request.result;
- $noteDetail.html("<h2>"+note.title+"</h2><p>"+note.body+"</p>").show();
- $noteForm.hide();
- };
- });
- $("#addNoteButton").on("click", function(e) {
- $("#title").val("");
- $("#body").val("");
- $("#key").val("");
- $noteDetail.hide();
- $noteForm.show();
- });
只要用戶讀過(guò)本系列教程的第一篇,就應(yīng)該知道上面的代碼并不復(fù)雜,關(guān)鍵點(diǎn)是無(wú)論是編輯還是刪除記事,都是必須先找出其id,這其實(shí)通過(guò)普通的DOM操作就可以實(shí)現(xiàn)了。接下來(lái)看保存記事的代碼:
- $("#saveNoteButton").on("click",function() {
- var title = $("#title").val();
- var body = $("#body").val();
- var key = $("#key").val();
- var t = db.transaction(["note"], "readwrite");
- if(key === "") {
- t.objectStore("note")
- .add({title:title,body:body,updated:new Date()});
- } else {
- t.objectStore("note")
- .put({title:title,body:body,updated:new Date(),id:Number(key)});
- }
- t.oncomplete = function(event) {
- $("#key").val("");
- $("#title").val("");
- $("#body").val("");
- displayNotes();
- $noteForm.hide();
- };
- return false;
- });
- });
在上面的代碼中,通過(guò)IF語(yǔ)句去判斷KEY是否為空,如果是空的話則表示是新增加記錄,否則就是在更新記錄。
在本系列教程的下一講,將重點(diǎn)介紹IndexedDB 的檢索功能和數(shù)組方面的功能。本講的代碼可以在如下連接下載:https://github.com/tutsplus/working-with-indexeddb-part-two
原文鏈接:http://net.tutsplus.com/tutorials/javascript-ajax/working-with-indexeddb-part-2/