前者的数据库,索引型数据库的待办事项简要列表

by admin on 2019年1月31日

前者的数据库:IndexedDB入门

2014/12/27 · 未分类 · IndexedDB

本文由 伯乐在线 –
cucr
翻译,黄利民
校稿。未经许可,禁止转发!
英文出处:www.codemag.com。欢迎加入翻译组。

应用程序要求多少。对大多数Web应用程序来说,数据在劳务器端协会和治本,客户端通过互连网请求获取。随着浏览器变得越来越有能力,因而可拔取在浏览器存储和操纵应用程序数据。

正文向你介绍名为IndexedDB的浏览器端文档数据库。使用lndexedDB,你可以因而惯于在劳务器端数据库大致相同的艺术开创、读取、更新和删除大量的笔录。请使用本文中可工作的代码版本去感受,完整的源代码可以透过GitHub库找到。

读到本课程的尾声时,你将熟稔IndexedDB的基本概念以及哪些贯彻一个用到IndexedDB执行总体的CRUD操作的模块化JavaScript应用程序。让我们稍事亲近IndexedDB并开端吧。

什么是IndexedDB

相似的话,有二种分裂品种的数据库:关系型和文档型(也称为NoSQL或对象)。关周全据库如SQL
Server,MySQL,Oracle的数据存储在表中。文档数据库如MongoDB,CouchDB,Redis将数据集作为个人对象存储。IndexedDB是一个文档数据库,它在完全内停放浏览器中的一个沙盒环境中(强制依据(浏览器)同源策略)。图1来得了IndexedDB的多少,体现了数据库的结构

必发88 1

图1:开发者工具查看一个object
store

成套的IndexedDB API请参考完整文档

深深解析HTML5中的IndexedDB索引数据库,html5indexeddb

那篇小说主要介绍了一语破的解析HTML5中的IndexedDB索引数据库,包罗事务锁等基本成效的连锁应用示例,要求的爱侣可以参见下

介绍 IndexedDB是HTML5 WEB数据库,允许HTML5
WEB应用在用户浏览器端存储数据。对于使用来说IndexedDB极度强大、有用,可以在客户端的chrome,IE,Firefox等WEB浏览器中储存多量数码,上边简单介绍一下IndexedDB的基本概念。
 
什么是IndexedDB IndexedDB,HTML5新的多少存储,能够在客户端存储、操作数据,可以使利用加载地更快,更好地响应。它不一样于关系型数据库,拥有数据表、记录。它影响着大家设计和创造应用程序的不二法门。IndexedDB
成立有数据类型和不难的JavaScript持久对象的object,每个object可以有目录,使其行之有效地查询和遍历整个集合。本文为您提供了哪些在Web应用程序中拔取IndexedDB的实事求是事例。
 
开始 咱俩须求在执行前包涵上面前置代码

JavaScript
Code复制内容到剪贴板

  1. var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
      
  2.     
  3. //prefixes of window.IDB objects   
  4. var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
      
  5. var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange
      
  6.     
  7. if (!indexedDB) {   
  8. alert(“Your browser doesn’t support a stable version of IndexedDB.”)
      
  9. }  

 
打开IndexedDB 在制造数据库从前,大家首先必要为数据库创立数量,借使大家有如下的用户音信:

JavaScript
Code复制内容到剪贴板

  1. var userData = [   
  2. { id: “1”, name: “Tapas”, age: 33, email: “[email protected]” },
      
  3. { id: “2”, name: “Bidulata”, age: 55, email: “[email protected]” }
      
  4. ];  

近年来我们须求用open()方法打开大家的数据库:

JavaScript
Code复制内容到剪贴板

  1. var db;   
  2. var request = indexedDB.open(“databaseName”, 1);   
  3.     
  4. request.onerror = function(e) {   
  5. console.log(“error: “, e);   
  6. };   
  7.     
  8. request.onsuccess = function(e) {   
  9. db = request.result;   
  10. console.log(“success: “+ db);   
  11. };   
  12. request.onupgradeneeded = function(e) {   
  13.     
  14. }  

如上所示,大家早就打开了名为”databaseName”,指定版本号的数据库,open()方法有五个参数:
1.先是个参数是数据库名称,它会检测名称为”databaseName”的数据库是不是曾经存在,如若存在则打开它,否则创造新的数据库。
2.次之个参数是数据库的本子,用于用户更新数据库结构。
 
onSuccess处理 发出成功事件时“onSuccess”被触发,纵然具有成功的呼吁都在此处理,大家得以因此赋值给db变量保存请求的结果供将来使用。
 
onerror的处理程序 暴发错误事件时“onerror”被触发,假若打开数据库的进程中破产。
 
Onupgradeneeded处理程序 一经你想翻新数据库(创立,删除或涂改数据库),那么你必须完毕onupgradeneeded处理程序,使您可以在数据库中做其它变更。
在“onupgradeneeded”处理程序中是可以更改数据库的布局的绝无仅有位置。
 
创制和增加数据到表:
IndexedDB使用对象存储来囤积数据,而不是因而表。
每当一个值存储在对象存储中,它与一个键相关联。
它同意大家创造的其余对象存储索引。
索引允许大家访问存储在目标存储中的值。
上面的代码呈现了怎么着成立对象存储并插入预先准备好的数目:

JavaScript
Code复制内容到剪贴板

  1. request.onupgradeneeded = function(event) {   
  2. var objectStore = event.target.result.createObjectStore(“users”, {keyPath: “id”});
      
  3. for (var i in userData) {   
  4. objectStore.add(userData[i]);    
  5. }   
  6. }  

俺们运用createObjectStore()方法成立一个目的存储。 此方法接受多个参数:

  • 储存的称呼和参数对象。
    在那边,大家有一个名为”users”的对象存储,并定义了keyPath,那是目标唯一性的属性。
    在此处,大家利用“id”作为keyPath,那几个值在目的存储中是绝无仅有的,大家务必有限支撑该“ID”的习性在对象存储中的每个对象中设有。
    一旦创设了目的存储,大家可以开首使用for循环添加数据进去。
     
    手动将数据增加到表:
    我们得以手动添加额外的多寡到数据库中。

JavaScript
Code复制内容到剪贴板

  1. function Add() {   
  2. var request = db.transaction([“users”], “readwrite”).objectStore(“users”)
      
  3. .add({ id: “3”, name: “Gautam”, age: 30, email: “[email protected]” });
      
  4.     
  5. request.onsuccess = function(e) {   
  6. alert(“Gautam has been added to the database.”);   
  7. 必发88,};   
  8.     
  9. request.onerror = function(e) {   
  10. alert(“Unable to add the information.”);    
  11. }   
  12.     
  13. }  

以前大家在数据库中做别的的CRUD操作(读,写,修改),必须运用工作。
该transaction()方法是用来指定大家想要举行事务处理的目的存储。
transaction()方法接受3个参数(第四个和第两个是可选的)。
首个是大家要拍卖的目标存储的列表,第一个指定大家是或不是要只读/读写,第七个是本子变化。
 
从表中读取数据 get()方法用于从目标存储中搜寻数据。
大家事先曾经安装对象的id作为的keyPath,所以get()方法将追寻具有同等id值的对象。
下边的代码将赶回我们命名为“Bidulata”的目的:

JavaScript
Code复制内容到剪贴板

  1. function Read() {   
  2. var objectStore = db.transaction([“users”]).objectStore(“users”);
      
  3. var request = objectStore.get(“2”);   
  4. request.onerror = function(event) {   
  5. alert(“Unable to retrieve data from database!”);   
  6. };   
  7. request.onsuccess = function(event) {    
  8. if(request.result) {   
  9. alert(“Name: ” + request.result.name + “, Age: ” + request.result.age + “, Email: ” + request.result.email);
      
  10. } else {   
  11. alert(“Bidulata couldn’t be found in your database!”);    
  12. }   
  13. };   
  14. }  

 
从表中读取所有数据
上面的点子寻找表中的所有数据。
那里大家选择游标来搜寻对象存储中的所有数据:

JavaScript
Code复制内容到剪贴板

  1. function ReadAll() {   
  2. var objectStore = db.transaction(“users”).objectStore(“users”); 
      
  3. var req = objectStore.openCursor();   
  4. req.onsuccess = function(event) {   
  5. db.close();   
  6. var res = event.target.result;   
  7. if (res) {   
  8. alert(“Key ” + res.key + ” is ” + res.value.name + “, Age: ” + res.value.age + “, Email: ” + res.value.email);
      
  9. res.continue();   
  10. }   
  11. };   
  12. req.onerror = function (e) {   
  13. console.log(“Error Getting: “, e);   
  14. };    
  15. }  

该openCursor()用于遍历数据库中的六个记录。
在continue()函数中继承读取下一条记下。
删除表中的记录 下边的主意从目标中除去记录。

JavaScript
Code复制内容到剪贴板

  1. function Remove() {    
  2. var request = db.transaction([“users”], “readwrite”).objectStore(“users”).delete(“1”);
      
  3. request.onsuccess = function(event) {   
  4. alert(“Tapas’s entry has been removed from your database.”);   
  5. };   
  6. }  

俺们要将对象的keyPath作为参数传递给delete()方法。
 
末尾代码
上边的点子从目标源中删除一条记下:

JavaScript
Code复制内容到剪贴板

  1. <!DOCTYPE html>  
  2. <head>  
  3. <meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />  
  4. <title>IndexedDB</title>  
  5. <script type=”text/javascript”>  
  6. var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
      
  7.     
  8. //prefixes of window.IDB objects   
  9. var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
      
  10. var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange
      
  11.     
  12. if (!indexedDB) {   
  13. alert(“Your browser doesn’t support a stable version of IndexedDB.”)
      
  14. }   
  15. var customerData = [   
  16. { id: “1”, name: “Tapas”, age: 33, email: “[email protected]” },
      
  17. { id: “2”, name: “Bidulata”, age: 55, email: “[email protected]” }
      
  18. ];   
  19. var db;   
  20. var request = indexedDB.open(“newDatabase”, 1);   
  21.     
  22. request.onerror = function(e) {   
  23. console.log(“error: “, e);   
  24. };   
  25.     
  26. request.onsuccess = function(e) {   
  27. db = request.result;   
  28. console.log(“success: “+ db);   
  29. };   
  30.     
  31. request.onupgradeneeded = function(event) {   
  32.     
  33. }   
  34. request.onupgradeneeded = function(event) {   
  35. var objectStore = event.target.result.createObjectStore(“users”, {keyPath: “id”});
      
  36. for (var i in userData) {   
  37. objectStore.add(userData[i]);    
  38. }   
  39. }   
  40. function Add() {   
  41. var request = db.transaction([“users”], “readwrite”)
      
  42. .objectStore(“users”)   
  43. .add({ id: “3”, name: “Gautam”, age: 30, email: “[email protected]” });
      
  44.     
  45. request.onsuccess = function(e) {   
  46. alert(“Gautam has been added to the database.”);   
  47. };   
  48.     
  49. request.onerror = function(e) {   
  50. alert(“Unable to add the information.”);    
  51. }   
  52.     
  53. }   
  54. function Read() {   
  55. var objectStore = db.transaction(“users”).objectStore(“users”);
      
  56. var request = objectStore.get(“2”);   
  57. request.onerror = function(event) {   
  58. alert(“Unable to retrieve data from database!”);   
  59. };   
  60. request.onsuccess = function(event) {    
  61. if(request.result) {   
  62. alert(“Name: ” + request.result.name + “, Age: ” + request.result.age + “, Email: ” + request.result.email);
      
  63. } else {   
  64. alert(“Bidulata couldn’t be found in your database!”);    
  65. }   
  66. };   
  67. }   
  68. function ReadAll() {   
  69. var objectStore = db.transaction(“users”).objectStore(“users”); 
      
  70. var req = objectStore.openCursor();   
  71. req.onsuccess = function(event) {   
  72. db.close();   
  73. var res = event.target.result;   
  74. if (res) {   
  75. alert(“Key ” + res.key + ” is ” + res.value.name + “, Age: ” + res.value.age + “, Email: ” + res.value.email);
      
  76. res.continue();   
  77. }   
  78. };   
  79. req.onerror = function (e) {   
  80. console.log(“Error Getting: “, e);   
  81. };    
  82. }   
  83. function Remove() {    
  84. var request = db.transaction([“users”], “readwrite”).objectStore(“users”).delete(“1”);
      
  85. request.onsuccess = function(event) {   
  86. alert(“Tapas’s entry has been removed from your database.”);   
  87. };   
  88. }   
  89. </script>  
  90. </head>  
  91.     
  92. <body>  
  93. <button onclick=”Add()”>Add record</button>  
  94. <button onclick=”Remove()”>Delete record</button>  
  95. <button onclick=”Read()”>Retrieve single record</button>  
  96. <button onclick=”ReadAll()”>Retrieve all records</button>  
  97. </body>  
  98. </html>  

localStorage是不带lock成效的。那么要贯彻前端的多寡共享并且必要lock功用那就须求动用别的本储存格局,比如indexedDB。indededDB使用的是事务处理的机制,那其实就是lock功能。
  做这几个测试需求先简单的包装下indexedDB的操作,因为indexedDB的总是相比费心,而且三个测试页面都急需用到

JavaScript
Code复制内容到剪贴板

  1. //db.js   
  2. //封装事务操作   
  3. IDBDatabase.prototype.doTransaction=function(f){   
  4.   f(this.transaction([“Obj”],”readwrite”).objectStore(“Obj”));   
  5. };   
  6. 前者的数据库,索引型数据库的待办事项简要列表。//连接数据库,成功后调用main函数   
  7. (function(){   
  8.   //打开数据库   
  9.   var cn=indexedDB.open(“TestDB”,1);   
  10.   //创制数量对象   
  11.   cn.onupgradeneeded=function(e){   
  12. 前者的数据库,索引型数据库的待办事项简要列表。    e.target.result.createObjectStore(“Obj”);   
  13.   };   
  14.   //数据库连接成功   
  15.   cn.onsuccess=function(e){   
  16.     main(e.target.result);   
  17.   };   
  18. })();   
  19.   接着是多个测试页面   
  20. <script src=”db.js”></script>  
  21. <script>  
  22. //a.html   
  23. function main(e){   
  24.   (function callee(){   
  25.     //起首一个政工   
  26.     e.doTransaction(function(e){   
  27.       e.put(1,”test”); //设置test的值为1   
  28.       e.put(2,”test”); //设置test的值为2   
  29.     });   
  30.     setTimeout(callee);   
  31.   })();   
  32. };   
  33. </script>  
  34. <script src=”db.js”></script>  
  35. <script>  
  36. //b.html   
  37. function main(e){   
  38.   (function callee(){   
  39.     //开首一个作业   
  40.     e.doTransaction(function(e){   
  41.       //获取test的值   
  42.       e.get(“test”).onsuccess=function(e){   
  43.         console.log(e.target.result);   
  44.       };   
  45.     });   
  46.     setTimeout(callee);   
  47.   })();   
  48. };   
  49. </script>  

把localStorage换成了indexedDB事务处理。不过结果就分歧

必发88 2

测试的时候b.html中或者不会应声有出口,因为indexedDB正忙着处理a.html东西,b.html事务丢在了工作丢队列中等待。不过无论怎么样,输出结果也不会是1那么些值。因为indexedDB的微乎其微处理单位是业务,而不是localStorage这样以表明式为单位。那样只要把lock和unlock之间要求处理的东西放入一个事务中即可完结。别的,浏览器对indexedDB的辅助不如localStorage,所以利用时还得考虑浏览器包容。

那篇文章紧要介绍了一语道破解析HTML5中的IndexedDB索引数据库,包蕴事务锁等基本作用的有关使…

简介

正文转自:

统筹指南

IndexedDB的架构很像在部分盛行的服务器端NOSQL数据库达成中的设计规范类型。面向对象数据通过object
stores(对象仓库)举办持久化,所有操作基于请求同时在作业限制内推行。事件生命周期使你可以决定数据库的配备,错误通过荒谬冒泡来使用API管理。

IndexedDB是HTML5中的新增效益。互联网数据库托管并留存在用户的浏览器内。只要让开发人员通过充分的查询作用创设应用,就足以预言到,将汇合世可以同时在线和离线使用的新星互连网选拔。

 

目的仓库

object
store是IndexedDB数据库的基本功。如若您使用过关全面据库,经常能够将object
store等价于一个多少库表。Object
stores蕴含一个或多少个目录,在store中服从一对键/值操作,那提供一种高效稳定数据的法门。

当您布署一个object
store,你必须为store选拔一个键。键在store中可以以“in-line”或“out-of-line”的措施存在。in-line键通过在数额对象上引用path来维持它在object
store的唯一性。为了印证那一点,想想一个席卷电子邮件地址属性Person对象。您可以安插你的store使用in-line键emailAddress,它能保障store(持久化对象中的数据)的唯一性。其余,out-of-line键通过独立于数据的值识别唯一性。在那种气象下,你可以把out-of-line键比作一个平头值,它(整数值)在关周详据库中担任记录的主键。

图1彰显了义务数据保存在任务的object
store,它应用in-line键。在这么些案例中,键对应于对象的ID值。

 

<!DOCTYPE
html>
<html>
  <head>
 
  <style>
 
    body {
 
      color: #222;
 
      font: 14px Arial;
 
    }
 
    
 
    body a {
 
      color: #3D5C9D;
 
      text-decoration: none;
 
    }
 
  </style>
 
  <script>
 
    var html5rocks = {};
 
    window.indexedDB = window.indexedDB || window.webkitIndexedDB ||
 
                       window.mozIndexedDB;
 
    
 
    if (‘webkitIndexedDB’ in window) {
 
      window.IDBTransaction = window.webkitIDBTransaction;
 
      window.IDBKeyRange = window.webkitIDBKeyRange;
 
    }
 
    
 
    html5rocks.indexedDB = {};
 
    html5rocks.indexedDB.db = null;
 
    
 
    html5rocks.indexedDB.onerror = function(e) {
 
      console.log(e);
 
    };
 
    
 
    html5rocks.indexedDB.open = function() {
 
      var request = indexedDB.open(“todos”);
 
    
 
      request.onsuccess = function(e) {
 
        var v = 1;
 
        html5rocks.indexedDB.db = e.target.result;
 
        var db = html5rocks.indexedDB.db;
 
        //
We can only create Object stores in a setVersion transaction;
 
        if (v != db.version) {
 
          var setVrequest = db.setVersion(v);
 
    
 
          //
onsuccess is the only place we can create Object Stores
 
          setVrequest.onerror = html5rocks.indexedDB.onerror;
 
          setVrequest.onsuccess = function(e) {
 
            if(db.objectStoreNames.contains(“todo”)) {
 
              db.deleteObjectStore(“todo”);
 
            }
 
    
 
            var store = db.createObjectStore(“todo”,
 
              {keyPath: “timeStamp”});
 
            e.target.transaction.oncomplete = function() {
 
              html5rocks.indexedDB.getAllTodoItems();
 
            };
 
          };
 
        } else {
 
          request.transaction.oncomplete = function() {
 
            html5rocks.indexedDB.getAllTodoItems();
 
          };
 
        }
 
      };
 
      request.onerror = html5rocks.indexedDB.onerror;
 
    };
 
    
 
    html5rocks.indexedDB.addTodo = function(todoText) {
 
      var db = html5rocks.indexedDB.db;
 
      var trans = db.transaction([“todo”], “readwrite”);
 
      var store = trans.objectStore(“todo”);
 
    
 
      var data = {
 
        “text”: todoText,
 
        “timeStamp”: new Date().getTime()
 
      };
 
    
 
      var request = store.put(data);
 
    
 
      request.onsuccess = function(e) {
 
        html5rocks.indexedDB.getAllTodoItems();
 
      };
 
    
 
      request.onerror = function(e) {
 
        console.log(“Error
Adding: “, e);
 
      };
 
    };
 
    
 
    html5rocks.indexedDB.deleteTodo = function(id) {
 
      var db = html5rocks.indexedDB.db;
 
      var trans = db.transaction([“todo”], “readwrite”);
 
      var store = trans.objectStore(“todo”);
 
    
 
      var request = store.delete(id);
 
    
 
      request.onsuccess = function(e) {
 
        html5rocks.indexedDB.getAllTodoItems();
 
      };
 
    
 
      request.onerror = function(e) {
 
        console.log(“Error
Adding: “, e);
 
      };
 
    };
 
    
 
    html5rocks.indexedDB.getAllTodoItems = function() {
 
      var todos = document.getElementById(“todoItems”);
 
      todos.innerHTML = “”;
 
    
 
      var db = html5rocks.indexedDB.db;
 
      var trans = db.transaction([“todo”], “readwrite”);
 
      var store = trans.objectStore(“todo”);
 
    
 
      //
Get everything in the store;
 
      var cursorRequest = store.openCursor();
 
    
 
      cursorRequest.onsuccess = function(e) {
 
        var result = e.target.result;
 
        if(!!result == false)
 
          return;
 
    
 
        renderTodo(result.value);
 
        result.continue();
 
      };
 
    
 
      cursorRequest.onerror = html5rocks.indexedDB.onerror;
 
    };
 
    
 
    function renderTodo(row) {
 
      var todos = document.getElementById(“todoItems”);
 
      var li = document.createElement(“li”);
 
      var a = document.createElement(“a”);
 
      var t = document.createTextNode(row.text);
 
    
 
      a.addEventListener(“click”, function() {
 
        html5rocks.indexedDB.deleteTodo(row.timeStamp);
 
      }, false);
 
    
 
      a.textContent = ”
[Delete]”;
 
      li.appendChild(t);
 
      li.appendChild(a);
 
      todos.appendChild(li);
 
    }
 
    
 
    function addTodo() {
 
      var todo = document.getElementById(“todo”);
 
      html5rocks.indexedDB.addTodo(todo.value);
 
      todo.value = “”;
 
    }
 
    
 
    function init() {
 
      html5rocks.indexedDB.open();
 
    }
 
    
 
    window.addEventListener(“DOMContentLoaded”, init, false);
 
  </script>
  </head>
  <body>
 
  <ul id=”todoItems”></ul>
 
  <input type=”text” id=”todo” name=”todo” placeholder=”What
do you need to do?” style=”width:
200px;” />
 
  <input type=”submit” value=”Add
Todo Item” onclick=”addTodo();
return false;”/>
  </body>
</html>​

依据事务

差别于一些传统的关周详据库的贯彻,每一个对数据库操作是在一个作业的内外文中执行的。事务限制三回影响一个或三个object
stores,你通过传播一个object store名字的数组到开创工作限制的函数来定义。

创建工作的第四个参数是业务情势。当呼吁一个事务时,必须控制是循序渐进只读照旧读写形式请求访问。事务是资源密集型的,所以只要您不须要更改data
store中的数据,你只必要以只读形式对object stores集合进行呼吁访问。

清单2示范了如何运用分外的形式创制一个作业,并在那片小说的 Implementing
Database-Specific Code
 部分开展了详尽座谈。

IndexedDB是什么?

依照请求

直到那里,有一个往往出现的焦点,您或许已经注意到。对数据库的每一趟操作,描述为经过一个呼吁打开数据库,访问一个object
store,再持续。IndexedDB
API天生是基于请求的,那也是API异步本性提示。对于你在数据库执行的每一次操作,你必须首先为这些操作创制一个伸手。当呼吁已毕,你可以响应由请求结果发生的风云和不当。

正文已毕的代码,演示了什么利用请求打开数据库,创设一个作业,读取object
store的情节,写入object store,清空object store。

IndexedDB是目的存储,它差别于带有表格(包罗行和列的会晤)的关周密据库。那是一个第一的平素不一样,并且会影响你设计和创设利用的主意。

打开数据库的呼吁生命周期

IndexedDB使用事件生命周期管理数据库的开辟和配置操作。图2演示了一个开拓的哀告在早晚的环境下爆发upgrade
need事件。

必发88 3

图2:IndexedDB打开请求的生命周期

具备与数据库的互相初叶于一个打开的伏乞。试图打开数据库时,您必须传递一个被呼吁数据库的本子号的整数值。在开拓请求时,浏览器比较你传入的用来打开请求的版本号与实际数据库的版本号。要是所请求的版本号高于浏览器中当前的版本号(或者现在尚无存在的数据库),upgrade
needed事件触发。在uprade
need事件之间,你有机遇通过抬高或移除stores,键和索引来操纵object stores。

万一所请求的数据库版本号和浏览器的当下版本号一致,或者升级进度一呵而就,一个开拓的数据库将回来给调用者。

 

不当冒泡

本来,有时候,请求可能不会按预期达成。IndexedDB
API通过荒谬冒泡效果来救助跟踪和保管漏洞百出。假如一个一定的请求蒙受错误,你可以尝尝在呼吁对象上处理错误,或者你可以允许错误通过调用栈冒泡向上传递。这几个冒泡天性,使得你不必要为种种请求落成特定错误处理操作,而是可以选拔只在一个更高级别上添加错误处理,它给你一个机遇,保持您的错误处理代码简洁。本文中落到实处的例证,是在一个高级别处理错误,以便更细粒度操作爆发的别样不当冒泡到通用的错误处理逻辑。

在观念的关全面据存储中,大家有一个“待办事项”的表格,其中各行存储了用户待办事项数据的聚合,而各列则是多少的命名类型。要插入数据,常常选拔如下语义:INSERTINTO
Todo(id, data, update_time) VALUES (1, “Test”,”01/01/2010″);

浏览器协助

莫不在开发Web应用程序最重大的难点是:“浏览器是或不是协助自己想要做的?“尽管浏览器对IndexedDB的支撑在此起彼伏狠抓,选择率并不是咱们所愿意的那样普遍。图3突显了caniuse.com网站的告诉,援救IndexedDB的为66%多一点点。最新版本的银狐,Chrome,Opera,Safar,iOS
Safari,和Android完全匡助IndexedDB,Internet
Explorer和小米部分帮忙。就算这么些列表的维护者是冲动的,但它并未报告所有故事。

必发88 4

图3:浏览器对IndexedDB的支撑,来自caniuse.com

唯有足够新本子的Safari和iOS Safari
辅助IndexedDB。据caniuse.com显示,那只占几乎0.01%的大世界浏览器采纳。IndexedDB不是一个你觉得可以理所当然得到支持的现代Web
API,不过你将神速会这么认为。

 

另一种拔取

浏览器协理地点数据库并不是从IndexedDB才初阶落成,它是在WebSQL贯彻之后的一种新点子。类似IndexedDB,WebSQL是一个客户端数据库,但它作为一个关周到据库的兑现,使用结构化查询语言(SQL)与数据库通讯。WebSQL的历史充满了曲折,但底线是绝非主流的浏览器厂商对WebSQL继续支持。

若果WebSQL实际上是一个丢掉的技艺,为何还要提它吧?有趣的是,WebSQL在浏览器里拿走逐步的支撑。Chrome,
Safari, iOS Safari, and
Android 浏览器都支持。其它,并不是那么些浏览器的风靡版本才提供支撑,许多那几个新式最好的浏览器从前的版本也得以支撑。有趣的是,假设您为WebSQL添加援救来支持IndexedDB,你突然发现,许多浏览器厂商和本子成为支撑浏览器内置数据库的某种化身。

从而,假诺你的应用程序真正须要一个客户端数据库,你想要达到的最高级其他使用可能,当IndexedDB不可用时,也许你的应用程序可能看起来要求选择使用WebSQL来支持客户端数据架构。尽管文档数据库和关周密据库管理数据有鲜明的距离,但一旦你有正确的抽象,就足以行使当地数据库构建一个应用程序。

IndexedDB的差异之处在于,您可以创建某个项目数据的对象存储,然后只需将JavaScript对象留存在该存储中即可。每个对象存储都得以有目录的集纳,那样就能展开快速的询问和迭代。

IndexedDB是或不是切合我的应用程序?

现行最器重的难题:“IndexedDB是或不是切合自己的应用程序?“像过去相同,答案是自然的:“视情形而定。“首先当你打算在客户端保存数据时,你会考虑HTML5当地存储。本地存储获得周边浏览器的帮助,有万分简单使用的API。不难有其优势,但其逆风局是不可以支撑复杂的查找策略,存储多量的数额,并提供业务帮忙。

IndexedDB是一个数据库。所以,当您想为客户端做出决定,考虑你如何在服务端选用一个持久化介质的数据库。你恐怕会问自己有些题材来帮衬控制客户端数据库是不是相符你的应用程序,包罗:

  • 您的用户通过浏览器访问您的应用程序,(浏览器)帮衬IndexedDB API吗 ?
  • 您必要仓储多量的数据在客户端?
  • 您须要在一个特大型的数码集合中快速稳定单个数据点?
  • 你的架构在客户端须要工作协理啊?

要是你对里面的其它难点答问了“是的”,很有可能,IndexedDB是您的应用程序的一个很好的候选。

 

使用IndexedDB

明天,你早已有机遇熟稔了有的的总体概念,下一步是发端落到实处基于IndexedDB的应用程序。第四个步骤须要统一IndexedDB在分化浏览器的兑现。您可以很不难地加上各类厂商特性的选取的自我批评,同时在window对象上把它们设置为合法对象相同的名称。上边的清单突显了window.indexedDB,window.IDBTransaction,window.IDBKeyRange的末梢结出是什么都被更新,它们被设置为相应的浏览器的一定完毕。

JavaScript

window.indexedDB = window.indexedDB || window.mozIndexedDB ||
window.webkitIndexedDB || window.msIndexedDB; window.IDBTransaction =
window.IDBTransaction || window.webkitIDBTransaction ||
window.msIDBTransaction; window.IDBKeyRange = window.IDBKeyRange ||
window.webkitIDBKeyRange || window.msIDBKeyRange;

1
2
3
4
5
6
7
8
9
10
window.indexedDB = window.indexedDB ||
                   window.mozIndexedDB ||
                   window.webkitIndexedDB ||
                   window.msIndexedDB;
window.IDBTransaction = window.IDBTransaction ||
                   window.webkitIDBTransaction ||
                   window.msIDBTransaction;
window.IDBKeyRange = window.IDBKeyRange ||
                   window.webkitIDBKeyRange ||
                   window.msIDBKeyRange;

近来,每个数据库相关的全局对象拥有正确的版本,应用程序可以准备使用IndexedDB起头工作。

IndexedDB 还废除了正式查询语言(
SQL)的定义,取而代之的是对准索引的询问,那样可以生出一个指南针,用于在结果集以内迭代。

利用概述

在本教程中,您将学习如何创设一个使用IndexedDB存储数据的模块化JavaScript应用程序。为了打探应用程序是怎么着行事的,参考图4,它讲述了任务应用程序处于空白状态。从那里你可以为列表添加新义务。图5显得了录入了多少个职务到系统的镜头。图6来得怎么删除一个任务,图7彰显了正在编制职务时的应用程序。

必发88 5

图4:空白的任务应用程序

必发88 6

图5:任务列表

必发88 7

图6:删除任务

必发88 8

图7:编辑任务
现今您熟习的应用程序的法力,下一步是从头为网站铺设基础。

 

铺设基础

本条例子从贯彻如此一个模块开首,它负责从数据库读取数据,插入新的靶子,更新现有对象,删除单个对象和提供在一个object
store删除所有目的的选项。这几个事例完成的代码是通用的多寡访问代码,您可以在任何object
store上选用。

那一个模块是通过一个随即施行函数表明式(IIFE)完成,它利用对象字面量来提供社团。上面的代码是模块的摘要,表明了它的着力构造。

JavaScript

(function (window) { ‘use strict’; var db = { /* implementation here
*/ }; window.app = window.app || {}; window.app.db = db; }(window));

1
2
3
4
5
6
7
8
(function (window) {
    ‘use strict’;
    var db = {
        /* implementation here */
    };
    window.app = window.app || {};
    window.app.db = db;
}(window));

用这么的社团,能够使那么些应用程序的兼具逻辑封装在一个名为app的单对象上。其它,数据库相关的代码在一个号称db的app子对象上。

本条模块的代码应用IIFE,通过传递window对象来保管模块的适龄限制。使用use
strict确保那么些函数的代码函数是根据(javascript严峻方式)严谨编译规则。db对象作为与数据库交互的兼具函数的要紧容器。最终,window对象检查app的实例是或不是存在,即使存在,模块使用当前实例,如若不设有,则创立一个新对象。一旦app对象成功重临或创办,db对象附加到app对象。

本文的其他部分将代码添加到db对象内(在implementation
here会
评价),为应用程序提供一定于数据库的逻辑。由此,如您所见本文前边的部分中定义的函数,想想父db对象活动,但所有其余职能都是db对象的积极分子。完整的数据库模块列表见清单2。

本课程只是举了一个事实上示例,告诉您针对编写为利用WebSQL
的共处应用怎么样使用IndexedDB。 

Implementing Database-Specific Code

对数据库的各样操作关联着一个先决条件,即有一个开拓的数据库。当数据库正在被打开时,通过检查数据库版本来判断数据库是或不是要求其他改动。下边的代码突显了模块怎么样跟踪当前版本,object
store名、某成员(保存了一旦数据库打开请求落成后的数据库当前实例)。

JavaScript

version: 1, objectStoreName: ‘tasks’, instance: {},

1
2
3
version: 1,
objectStoreName: ‘tasks’,
instance: {},

在那边,数据库打开请求暴发时,模块请求版本1数据库。若是数据库不存在,或者版本小于1,upgrade
needed事件在开拓请求已毕前触发。那些模块被设置为只行使一个object
store,所以名字直接定义在那里。最后,实例成员被成立,它用于保存一旦打开请求达成后的数据库当前实例。

接下去的操作是兑现upgrade
needed事件的事件处理程序。在此地,检查当前object
store的名字来判定请求的object store名是还是不是留存,假如不存在,成立object
store。

JavaScript

upgrade: function (e) { var _db = e.target.result, names =
_db.objectStoreNames, name = db.objectStoreName; if
(!names.contains(name)) { _db.createObjectStore( name, { keyPath: ‘id’,
autoIncrement: true }); } },

1
2
3
4
5
6
7
8
9
10
11
12
13
14
upgrade: function (e) {
    var
        _db = e.target.result,
        names = _db.objectStoreNames,
        name = db.objectStoreName;
    if (!names.contains(name)) {
        _db.createObjectStore(
            name,
            {
                keyPath: ‘id’,
                autoIncrement: true
            });
    }
},

在这几个事件处理程序里,通过事件参数e.target.result来访问数据库。当前的object
store名称的列表在_db.objectStoreName的字符串数组上。现在,假设object
store不存在,它是通过传递object
store名称和store的键的概念(自增,关联到数量的ID成员)来成立。

模块的下一个作用是用来捕获错误,错误在模块分化的呼吁成立时冒泡。

JavaScript

errorHandler: function (error) { window.alert(‘error: ‘ +
error.target.code); debugger; },

1
2
3
4
errorHandler: function (error) {
    window.alert(‘error: ‘ + error.target.code);
    debugger;
},

在此地,errorHandler在一个警告框彰显其余不当。那么些函数是蓄意保持简单,对开发协调,当您读书使用IndexedDB,您可以很不难地看出其余错误(当她们暴发时)。当您准备在生养环境使用那一个模块,您须要在那些函数中贯彻部分错误处理代码来和您的应用程序的上下文打交道。

当今基础已毕了,这一节的其他部分将演示怎么样已毕对数据库执行一定操作。第三个要求检讨的函数是open函数。

JavaScript

open: function (callback) { var request = window.indexedDB.open(
db.objectStoreName, db.version); request.onerror = db.errorHandler;
request.onupgradeneeded = db.upgrade; request.onsuccess = function (e) {
db.instance = request.result; db.instance.onerror = db.errorHandler;
callback(); }; },

1
2
3
4
5
6
7
8
9
10
11
12
open: function (callback) {
    var request = window.indexedDB.open(
        db.objectStoreName, db.version);
    request.onerror = db.errorHandler;
    request.onupgradeneeded = db.upgrade;
    request.onsuccess = function (e) {
        db.instance = request.result;
        db.instance.onerror =
            db.errorHandler;
        callback();
    };
},

open函数试图打开数据库,然后实施回调函数,告知数据库成功打开方可准备利用。通过走访window.indexedDB调用open函数来创立打开请求。那么些函数接受你想打开的object
store的称号和您想使用的数据库版本号。

假使请求的实例可用,第一步要举办的劳作是安装错误处理程序和升级函数。记住,当数据库被打开时,假如脚本请求比浏览器里更高版本的数据库(或者只要数据库不设有),升级函数运行。不过,假如请求的数据库版本匹配当前数据库版本同时没有不当,success事件触发。

借使一切成功,打开数据库的实例可以从呼吁实例的result属性得到,这几个实例也缓存到模块的实例属性。然后,onerror事件设置到模块的errorHandler,作为将来其余请求的荒谬捕捉处理程序。最后,回调被实施来报告调用者,数据库已经打开并且正确地布局,可以利用了。

下一个要促成的函数是helper函数,它回到所请求的object store。

JavaScript

getObjectStore: function (mode) { var txn, store; mode = mode ||
‘readonly’; txn = db.instance.transaction( [db.objectStoreName],
mode); store = txn.objectStore( db.objectStoreName); return store; },

1
2
3
4
5
6
7
8
9
getObjectStore: function (mode) {
    var txn, store;
    mode = mode || ‘readonly’;
    txn = db.instance.transaction(
        [db.objectStoreName], mode);
    store = txn.objectStore(
        db.objectStoreName);
    return store;
},

在此间,getObjectStore接受mode参数,允许你决定store是以只读如故读写方式请求。对于那么些函数,默许mode是只读的。

每个针对object
store的操作都是在一个事物的上下文中执行的。事务请求接受一个object
store名字的数组。这些函数本次被布署为只利用一个object
store,不过一旦您须求在工作中操作多少个object store,你须求传递多个object
store的名字到数组中。事务函数的第三个参数是一个格局。

若是事情请求可用,您就可以因而传递要求的object
store名字来调用objectStore函数以赢得object
store实例的访问权。那些模块的别的函数使用getObjectStore来收获object
store的访问权。

下一个完结的函数是save函数,执行插入或更新操作,它按照传入的数额是或不是有一个ID值。

JavaScript

save: function (data, callback) { db.open(function () { var store,
request, mode = ‘readwrite’; store = db.getObjectStore(mode), request =
data.id ? store.put(data) : store.add(data); request.onsuccess =
callback; }); },

1
2
3
4
5
6
7
8
9
10
11
12
save: function (data, callback) {
    db.open(function () {
        var store, request,
            mode = ‘readwrite’;
 
        store = db.getObjectStore(mode),
        request = data.id ?
            store.put(data) :
            store.add(data);
        request.onsuccess = callback;
    });
},

save函数的八个参数分别是内需保留的多少对象实例和操作成功后须求进行的回调。读写形式用于将数据写入数据库,它被传出到getObjectStore来收获object
store的一个可写实例。然后,检查数据对象的ID成员是还是不是存在。就算存在ID值,数据必须立异,put函数被调用,它制造持久化请求。否则,若是ID不存在,那是新数据,add请求重临。最后,不管put或者add
请求是或不是履行了,success事件处理程序要求设置在回调函数上,来报告调用脚本,一切进展顺遂。

下一节的代码在清单1所示。getAll函数首先打开数据库和做客object
store,它为store和cursor(游标)分别设置值。为数据库游标设置游标变量允许迭代object
store中的数据。data变量设置为一个空数组,充当数据的器皿,它回到给调用代码。

在store访问数据时,游标遍历数据库中的每条记下,会触发onsuccess事件处理程序。当每条记下走访时,store的多寡可以透过e.target.result事件参数得到。即使事实上数据从target.result的value属性中取得,首先要求在总计访问value属性前确保result是一个实用的值。如若result存在,您可以添加result的值到数据数组,然后在result对象上调用continue函数来持续迭代object
store。最后,如若没有reuslt了,对store数据的迭代为止,同时数据传递到回调,回调被实践。

前日模块能够从data
store获得所有数据,下一个亟待已毕的函数是背负访问单个记录。

JavaScript

get: function (id, callback) { id = parseInt(id); db.open(function () {
var store = db.getObjectStore(), request = store.get(id);
request.onsuccess = function (e){ callback(e.target.result); }; }); },

1
2
3
4
5
6
7
8
9
10
11
get: function (id, callback) {
    id = parseInt(id);
    db.open(function () {
        var
            store = db.getObjectStore(),
            request = store.get(id);
        request.onsuccess = function (e){
            callback(e.target.result);
        };
    });
},

get函数执行的首先步操作是将id参数的值转换为一个平头。取决于函数被调用时,字符串或整数都可能传递给函数。那些已毕跳过了对如若所给的字符串无法转换成整数该如何是好的情景的拍卖。一旦一个id值准备好了,数据库打开了和object
store可以访问了。获取访问get请求出现了。请求成功时,通过传播e.target.result来举办回调。它(e.target.result)是经过调用get函数到手的单条记录。

今昔保留和甄选操作已经出现了,该模块还需求从object store移除数量。

JavaScript

‘delete’: function (id, callback) { id = parseInt(id); db.open(function
() { var mode = ‘readwrite’, store, request; store =
db.getObjectStore(mode); request = store.delete(id); request.onsuccess =
callback; }); },

1
2
3
4
5
6
7
8
9
10
11
‘delete’: function (id, callback) {
    id = parseInt(id);
    db.open(function () {
        var
            mode = ‘readwrite’,
            store, request;
        store = db.getObjectStore(mode);
        request = store.delete(id);
        request.onsuccess = callback;
    });
},

delete函数的称呼用单引号,因为delete是JavaScript的保留字。那足以由你来控制。您可以选用命名函数为del或其他名目,然而delete用在那几个模块为了API尽可能好的发挥。

传送给delete函数的参数是目的的id和一个回调函数。为了保险那么些完结简单,delete函数约定id的值为整数。您能够选用成立一个更结实的兑现来处理id值无法分析成整数的谬误例子的回调,但为了指引原因,代码示例是明知故犯的。

万一id值能有限帮助转换成一个平头,数据库被打开,一个可写的object
store得到,delete函数传入id值被调用。当呼吁成功时,将实施回调函数。

在少数意况下,您可能须要删除一个object
store的装有的记录。在那种情形下,您访问store同时免去所有情节。

JavaScript

deleteAll: function (callback) { db.open(function () { var mode, store,
request; mode = ‘readwrite’; store = db.getObjectStore(mode); request =
store.clear(); request.onsuccess = callback; }); }

1
2
3
4
5
6
7
8
9
deleteAll: function (callback) {
    db.open(function () {
        var mode, store, request;
        mode = ‘readwrite’;
        store = db.getObjectStore(mode);
        request = store.clear();
        request.onsuccess = callback;
    });
}

此间deleteAll函数负责打开数据库和访问object
store的一个可写实例。一旦store可用,一个新的请求通过调用clear函数来创制。一旦clear操作成功,回调函数被实践。

 

施行用户界面特定代码

明日有所特定于数据库的代码被封装在app.db模块中,用户界面特定代码可以应用此模块来与数据库交互。用户界面特定代码的总体清单(index.ui.js)可以在清单3中收获,完整的(index.html)页面的HTML源代码可以在清单4中拿走。

为啥是 IndexedDB?

结论

乘势应用程序的需求的滋长,你会意识在客户端高效存储多量的数量的优势。IndexedDB是可以在浏览器中一向利用且协理异步事务的文档数据库完成。纵然浏览器的协理可能依然不能保全,但在适宜的情事下,集成IndexedDB的Web应用程序具有强大的客户端数据的走访能力。

在一大半意况下,所有针对IndexedDB编写的代码是自然基于请求和异步的。官方正式有同步API,不过那种IndexedDB只适合web
worker的左右文中使用。那篇小说公布时,还未曾浏览器已毕的同台格式的IndexedDB
API。

毫无疑问要确保代码在其它函数域外对厂商特定的indexedDB, IDBTransaction, and
IDBKeyRange实例举办了规范化且使用了暴虐方式。那允许你防止浏览器错误,当在strict
mode下解析脚本时,它不会允许你对这些对象重新赋值。

你不能够不确保只传递正整数的本子号给数据库。传递到版本号的小数值会四舍五入。由此,即便您的数据库方今版本1,您准备访问1.2版本,upgrade-needed事件不会接触,因为版本号最后评估是平等的。

及时实施函数表达式(IIFE)有时叫做不一致的名字。有时可以看出这么的代码组织章程,它称作self-executing
anonymous functions(自实施匿名函数)或self-invoked anonymous
functions(自调用匿名函数)。为更为解释这几个名称相关的用意和意义,请阅读Ben
Alman的篇章Immediately Invoked Function Expression (IIFE) 。

Listing 1: Implementing the getAll function

JavaScript

getAll: function (callback) { db.open(function () { var store =
db.getObjectStore(), cursor = store.openCursor(), data = [];
cursor.onsuccess = function (e) { var result = e.target.result; if
(result && result !== null) { data.push(result.value);
result.continue(); } else { callback(data); } }; }); },

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
getAll: function (callback) {
 
    db.open(function () {
 
        var
            store = db.getObjectStore(),
            cursor = store.openCursor(),
            data = [];
 
        cursor.onsuccess = function (e) {
 
            var result = e.target.result;
 
            if (result &&
                result !== null) {
 
                data.push(result.value);
                result.continue();
 
            } else {
 
                callback(data);
            }
        };
 
    });
},

Listing 2: Full source for database-specific code
(index.db.js)

JavaScript

// index.db.js ; window.indexedDB = window.indexedDB ||
window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
window.IDBTransaction = window.IDBTransaction ||
window.webkitIDBTransaction || window.msIDBTransaction;
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange ||
window.msIDBKeyRange; (function(window){ ‘use strict’; var db = {
version: 1, // important: only use whole numbers! objectStoreName:
‘tasks’, instance: {}, upgrade: function (e) { var _db =
e.target.result, names = _db.objectStoreNames, name =
db.objectStoreName; if (!names.contains(name)) { _db.createObjectStore(
name, { keyPath: ‘id’, autoIncrement: true }); } }, errorHandler:
function (error) { window.alert(‘error: ‘ + error.target.code);
debugger; }, open: function (callback) { var request =
window.indexedDB.open( db.objectStoreName, db.version); request.onerror
= db.errorHandler; request.onupgradeneeded = db.upgrade;
request.onsuccess = function (e) { db.instance = request.result;
db.instance.onerror = db.errorHandler; callback(); }; }, getObjectStore:
function (mode) { var txn, store; mode = mode || ‘readonly’; txn =
db.instance.transaction( [db.objectStoreName], mode); store =
txn.objectStore( db.objectStoreName); return store; }, save: function
(data, callback) { db.open(function () { var store, request, mode =
‘readwrite’; store = db.getObjectStore(mode), request = data.id ?
store.put(data) : store.add(data); request.onsuccess = callback; }); },
getAll: function (callback) { db.open(function () { var store =
db.getObjectStore(), cursor = store.openCursor(), data = [];
cursor.onsuccess = function (e) { var result = e.target.result; if
(result && result !== null) { data.push(result.value);
result.continue(); } else { callback(data); } }; }); }, get: function
(id, callback) { id = parseInt(id); db.open(function () { var store =
db.getObjectStore(), request = store.get(id); request.onsuccess =
function (e){ callback(e.target.result); }; }); }, ‘delete’: function
(id, callback) { id = parseInt(id); db.open(function () { var mode =
‘readwrite’, store, request; store = db.getObjectStore(mode); request =
store.delete(id); request.onsuccess = callback; }); }, deleteAll:
function (callback) { db.open(function () { var mode, store, request;
mode = ‘readwrite’; store = db.getObjectStore(mode); request =
store.clear(); request.onsuccess = callback; }); } }; window.app =
window.app || {}; window.app.db = db; }(window));

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
// index.db.js
 
;
 
window.indexedDB = window.indexedDB ||
                   window.mozIndexedDB ||
                   window.webkitIndexedDB ||
                   window.msIndexedDB;
 
window.IDBTransaction = window.IDBTransaction ||
                   window.webkitIDBTransaction ||
                   window.msIDBTransaction;
 
window.IDBKeyRange = window.IDBKeyRange ||
                   window.webkitIDBKeyRange ||
                   window.msIDBKeyRange;
 
(function(window){
 
    ‘use strict’;
 
    var db = {
 
        version: 1, // important: only use whole numbers!
 
        objectStoreName: ‘tasks’,
 
        instance: {},
 
        upgrade: function (e) {
 
            var
                _db = e.target.result,
                names = _db.objectStoreNames,
                name = db.objectStoreName;
 
            if (!names.contains(name)) {
 
                _db.createObjectStore(
                    name,
                    {
                        keyPath: ‘id’,
                        autoIncrement: true
                    });
            }
        },
 
        errorHandler: function (error) {
            window.alert(‘error: ‘ + error.target.code);
            debugger;
        },
 
        open: function (callback) {
 
            var request = window.indexedDB.open(
                db.objectStoreName, db.version);
 
            request.onerror = db.errorHandler;
 
            request.onupgradeneeded = db.upgrade;
 
            request.onsuccess = function (e) {
 
                db.instance = request.result;
 
                db.instance.onerror =
                    db.errorHandler;
 
                callback();
            };
        },
 
        getObjectStore: function (mode) {
 
            var txn, store;
 
            mode = mode || ‘readonly’;
 
            txn = db.instance.transaction(
                [db.objectStoreName], mode);
 
            store = txn.objectStore(
                db.objectStoreName);
 
            return store;
        },
 
        save: function (data, callback) {
 
            db.open(function () {
 
                var store, request,
                    mode = ‘readwrite’;
 
                store = db.getObjectStore(mode),
 
                request = data.id ?
                    store.put(data) :
                    store.add(data);
 
                request.onsuccess = callback;
            });
        },
 
        getAll: function (callback) {
 
            db.open(function () {
 
                var
                    store = db.getObjectStore(),
                    cursor = store.openCursor(),
                    data = [];
 
                cursor.onsuccess = function (e) {
 
                    var result = e.target.result;
 
                    if (result &&
                        result !== null) {
 
                        data.push(result.value);
                        result.continue();
 
                    } else {
 
                        callback(data);
                    }
                };
 
            });
        },
 
        get: function (id, callback) {
 
            id = parseInt(id);
 
            db.open(function () {
 
                var
                    store = db.getObjectStore(),
                    request = store.get(id);
 
                request.onsuccess = function (e){
                    callback(e.target.result);
                };
            });
        },
 
        ‘delete’: function (id, callback) {
 
            id = parseInt(id);
 
            db.open(function () {
 
                var
                    mode = ‘readwrite’,
                    store, request;
 
                store = db.getObjectStore(mode);
 
                request = store.delete(id);
 
                request.onsuccess = callback;
            });
        },
 
        deleteAll: function (callback) {
 
            db.open(function () {
 
                var mode, store, request;
 
                mode = ‘readwrite’;
                store = db.getObjectStore(mode);
                request = store.clear();
 
                request.onsuccess = callback;
            });
 
        }
    };
 
    window.app = window.app || {};
    window.app.db = db;
 
}(window));

Listing 3: Full source for user interface-specific code
(index.ui.js)

JavaScript

// index.ui.js ; (function ($, Modernizr, app) { ‘use strict’;
$(function(){ if(!Modernizr.indexeddb){
$(‘#unsupported-message’).show(); $(‘#ui-container’).hide(); return; }
var $deleteAllBtn = $(‘#delete-all-btn’), $titleText =
$(‘#title-text’), $notesText = $(‘#notes-text’), $idHidden =
$(‘#id-hidden’), $clearButton = $(‘#clear-button’), $saveButton =
$(‘#save-button’), $listContainer = $(‘#list-container’),
$noteTemplate = $(‘#note-template’), $emptyNote = $(‘#empty-note’);
var addNoTasksMessage = function(){ $listContainer.append(
$emptyNote.html()); }; var bindData = function (data) {
$listContainer.html(”); if(data.length === 0){ addNoTasksMessage();
return; } data.forEach(function (note) { var m = $noteTemplate.html(); m
= m.replace(/{ID}/g, note.id); m = m.replace(/{TITLE}/g, note.title);
$listContainer.append(m); }); }; var clearUI = function(){
$titleText.val(”).focus(); $notesText.val(”); $idHidden.val(”); }; //
select individual item $listContainer.on(‘click’, ‘a[data-id]’,
function (e) { var id, current; e.preventDefault(); current =
e.currentTarget; id = $(current).attr(‘data-id’); app.db.get(id,
function (note) { $titleText.val(note.title); $notesText.val(note.text);
$idHidden.val(note.id); }); return false; }); // delete item
$listContainer.on(‘click’, ‘i[data-id]’, function (e) { var id,
current; e.preventDefault(); current = e.currentTarget; id =
$(current).attr(‘data-id’); app.db.delete(id, function(){
app.db.getAll(bindData); clearUI(); }); return false; });
$clearButton.click(function(e){ e.preventDefault(); clearUI(); return
false; }); $saveButton.click(function (e) { var title =
$titleText.val(); if (title.length === 0) { return; } var note = {
title: title, text: $notesText.val() }; var id = $idHidden.val(); if(id
!== ”){ note.id = parseInt(id); } app.db.save(note, function(){
app.db.getAll(bindData); clearUI(); }); }); $deleteAllBtn.click(function
(e) { e.preventDefault(); app.db.deleteAll(function () {
$listContainer.html(”); addNoTasksMessage(); clearUI(); }); return
false; }); app.db.errorHandler = function (e) { window.alert(‘error: ‘ +
e.target.code); debugger; }; app.db.getAll(bindData); }); }(jQuery,
Modernizr, window.app));

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// index.ui.js
 
;
 
(function ($, Modernizr, app) {
 
    ‘use strict’;
 
    $(function(){
 
        if(!Modernizr.indexeddb){
            $(‘#unsupported-message’).show();
            $(‘#ui-container’).hide();
            return;
        }
 
        var
          $deleteAllBtn = $(‘#delete-all-btn’),
          $titleText = $(‘#title-text’),
          $notesText = $(‘#notes-text’),
          $idHidden = $(‘#id-hidden’),
          $clearButton = $(‘#clear-button’),
          $saveButton = $(‘#save-button’),
          $listContainer = $(‘#list-container’),
          $noteTemplate = $(‘#note-template’),
          $emptyNote = $(‘#empty-note’);
 
        var addNoTasksMessage = function(){
            $listContainer.append(
                $emptyNote.html());
        };
 
        var bindData = function (data) {
 
            $listContainer.html(”);
 
            if(data.length === 0){
                addNoTasksMessage();
                return;
            }
 
            data.forEach(function (note) {
              var m = $noteTemplate.html();
              m = m.replace(/{ID}/g, note.id);
              m = m.replace(/{TITLE}/g, note.title);
              $listContainer.append(m);
            });
        };
 
        var clearUI = function(){
            $titleText.val(”).focus();
            $notesText.val(”);
            $idHidden.val(”);
        };
 
        // select individual item
        $listContainer.on(‘click’, ‘a[data-id]’,
 
            function (e) {
 
                var id, current;
 
                e.preventDefault();
 
                current = e.currentTarget;
                id = $(current).attr(‘data-id’);
 
                app.db.get(id, function (note) {
                    $titleText.val(note.title);
                    $notesText.val(note.text);
                    $idHidden.val(note.id);
                });
 
                return false;
            });
 
        // delete item
        $listContainer.on(‘click’, ‘i[data-id]’,
 
            function (e) {
 
                var id, current;
 
                e.preventDefault();
 
                current = e.currentTarget;
                id = $(current).attr(‘data-id’);
 
                app.db.delete(id, function(){
                    app.db.getAll(bindData);
                    clearUI();
                });
 
                return false;
        });
 
        $clearButton.click(function(e){
            e.preventDefault();
            clearUI();
            return false;
        });
 
        $saveButton.click(function (e) {
 
            var title = $titleText.val();
 
            if (title.length === 0) {
                return;
            }
 
            var note = {
                title: title,
                text: $notesText.val()
            };
 
            var id = $idHidden.val();
 
            if(id !== ”){
                note.id = parseInt(id);
            }
 
            app.db.save(note, function(){
                app.db.getAll(bindData);
                clearUI();
            });
        });
 
        $deleteAllBtn.click(function (e) {
 
            e.preventDefault();
 
            app.db.deleteAll(function () {
                $listContainer.html(”);
                addNoTasksMessage();
                clearUI();
            });
 
            return false;
        });
 
        app.db.errorHandler = function (e) {
            window.alert(‘error: ‘ + e.target.code);
            debugger;
        };
 
        app.db.getAll(bindData);
 
    });
 
}(jQuery, Modernizr, window.app));

Listing 3: Full HTML source (index.html)

JavaScript

<!doctype html> <html lang=”en-US”> <head> <meta
charset=”utf-8″> <meta http-equiv=”X-UA-Compatible”
content=”IE=edge”> <title>Introduction to
IndexedDB</title> <meta name=”description”
content=”Introduction to IndexedDB”> <meta name=”viewport”
content=”width=device-width, initial-scale=1″> <link
rel=”stylesheet”
href=”//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css”>
<link rel=”stylesheet” href=”//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/css/font-awesome.min.css” > <link
rel=”stylesheet” href=”//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/FontAwesome.otf” > <link
rel=”stylesheet” href=”//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.eot” > <link
rel=”stylesheet” href=”//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.svg” > <link
rel=”stylesheet” href=”//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.ttf” > <link
rel=”stylesheet” href=”//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.woff” > <style>
h1 { text-align: center; color:#999; } ul li { font-size: 1.35em;
margin-top: 1em; margin-bottom: 1em; } ul li.small { font-style: italic;
} footer { margin-top: 25px; border-top: 1px solid #eee; padding-top:
25px; } i[data-id] { cursor: pointer; color: #eee; }
i[data-id]:hover { color: #c75a6d; } .push-down { margin-top: 25px; }
#save-button { margin-left: 10px; } </style> <script
src=”//cdnjs.cloudflare.com/ajax/libs/modernizr /2.8.2/modernizr.min.js”
></script> </head> <body class=”container”>
<h1>Tasks</h1> <div id=”unsupported-message” class=”alert
alert-warning” style=”display:none;”> <b>Aww snap!</b>
Your browser does not support indexedDB. </div> <div
id=”ui-container” class=”row”> <div class=”col-sm-3″> <a
href=”#” id=”delete-all-btn” class=”btn-xs”> <i class=”fa
fa-trash-o”></i> Delete All</a> <hr/> <ul
id=”list-container” class=”list-unstyled”></ul> </div>
<div class=”col-sm-8 push-down”> <input type=”hidden”
id=”id-hidden” /> <input id=”title-text” type=”text”
class=”form-control” tabindex=”1″ placeholder=”title” autofocus
/><br /> <textarea id=”notes-text” class=”form-control”
tabindex=”2″ placeholder=”text”></textarea> <div
class=”pull-right push-down”> <a href=”#” id=”clear-button”
tabindex=”4″>Clear</a> <button id=”save-button” tabindex=”3″
class=”btn btn-default btn-primary”> <i class=”fa
fa-save”></i> Save</button> </div> </div>
</div> <footer class=”small text-muted text-center”>by <a
href=”” target=”_blank”>Craig
Shoemaker</a> <a href=””
target=”_blank”> <i class=”fa fa-twitter”></i></a>
</footer> <script id=”note-template” type=”text/template”>
<li> <i data-id=”{ID}” class=”fa fa-minus-circle”></i>
<a href=”#” data-id=”{ID}”>{TITLE}</a> </li>
</script> <script id=”empty-note” type=”text/template”>
<li class=”text-muted small”>No tasks</li> </script>
<script src=”//ajax.googleapis.com/ajax/libs
/jquery/1.11.1/jquery.min.js”></script> <script
src=”index.db.js” type=”text/javascript”></script> <script
src=”index.ui.js” type=”text/javascript”></script>
</body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
<!doctype html>
<html lang="en-US">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Introduction to IndexedDB</title>
        <meta name="description"
              content="Introduction to IndexedDB">
        <meta name="viewport"
              content="width=device-width, initial-scale=1">
        <link rel="stylesheet"
              href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/css/font-awesome.min.css" >
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/FontAwesome.otf" >
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.eot" >
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.svg" >
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.ttf" >
        <link rel="stylesheet"
              href="//cdnjs.cloudflare.com/ajax/libs
/font-awesome/4.1.0/fonts/fontawesome-webfont.woff" >
        <style>
            h1 {
                text-align: center;
                color:#999;
            }
 
            ul li {
                font-size: 1.35em;
                margin-top: 1em;
                margin-bottom: 1em;
            }
 
            ul li.small {
                font-style: italic;
            }
 
            footer {
                margin-top: 25px;
                border-top: 1px solid #eee;
                padding-top: 25px;
            }
 
            i[data-id] {
                cursor: pointer;
                color: #eee;
            }
 
            i[data-id]:hover {
                color: #c75a6d;
            }
 
            .push-down {
                margin-top: 25px;
            }
 
            #save-button {
                margin-left: 10px;
            }
        </style>
        <script src="//cdnjs.cloudflare.com/ajax/libs/modernizr
/2.8.2/modernizr.min.js" ></script>
    </head>
    <body class="container">
        <h1>Tasks</h1>
        <div id="unsupported-message"
             class="alert alert-warning"
             style="display:none;">
            <b>Aww snap!</b> Your browser does not support indexedDB.
        </div>
        <div id="ui-container" class="row">
            <div class="col-sm-3">
 
                <a href="#" id="delete-all-btn" class="btn-xs">
                    <i class="fa fa-trash-o"></i> Delete All</a>
 
                <hr/>
 
                <ul id="list-container" class="list-unstyled"></ul>
 
            </div>
            <div class="col-sm-8 push-down">
 
                <input type="hidden" id="id-hidden" />
 
                <input
                       id="title-text"
                       type="text"
                       class="form-control"
                       tabindex="1"
                       placeholder="title"
                       autofocus /><br />
 
                <textarea
                          id="notes-text"
                          class="form-control"
                          tabindex="2"
                          placeholder="text"></textarea>
 
                <div class="pull-right push-down">
 
                    <a href="#" id="clear-button" tabindex="4">Clear</a>
 
                    <button id="save-button"
                            tabindex="3"
                            class="btn btn-default btn-primary">
                                <i class="fa fa-save"></i> Save</button>
                </div>
            </div>
        </div>
        <footer class="small text-muted text-center">by
            <a href="http://craigshoemaker.net" target="_blank">Craig Shoemaker</a>
            <a href="http://twitter.com/craigshoemaker" target="_blank">
                <i class="fa fa-twitter"></i></a>
        </footer>
        <script id="note-template" type="text/template">
            <li>
                <i data-id="{ID}" class="fa fa-minus-circle"></i>
                <a href="#" data-id="{ID}">{TITLE}</a>
            </li>
        </script>
        <script id="empty-note" type="text/template">
            <li class="text-muted small">No tasks</li>
        </script>
        <script src="//ajax.googleapis.com/ajax/libs
/jquery/1.11.1/jquery.min.js"></script>
        <script src="index.db.js" type="text/javascript"></script>
        <script src="index.ui.js" type="text/javascript"></script>
    </body>
</html>

赞 1 收藏
评论

在 2010 年 6月 18 日,W3C宣布弃用Web
SQL数据库规范。这也就是指出互连网开发人士不要再选取那种技能了,该专业也不会再赢得新的更新,而且不鼓励浏览器供应商帮衬该技能。

关于作者:cucr

必发88 9

今日头条微博:@hop_ping
个人主页 ·
我的篇章 ·
17

必发88 10

 

代表的是
IndexedDB,本课程的焦点是开发人士应运用那种多少存储在客户端上囤积数据并拓展操作。

 

各大主流浏览器(包涵Chrome浏览器、Safari、Opera等)和大概拥有基于Webkit的移位设备均协助WebSQL,并且很有可能在可预感的前程持续提供辅助。

 

先决条件

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

 

[html] 

var html5rocks = {};  html5rocks.indexedDB = {};  var html5rocks = {};

html5rocks.indexedDB = {};异步和事务性

在大部状态下,假使你使用的是索引型数据库,那么就会利用异步API。异步API是非阻塞系统,因而不会经过重返值得到数量,而是获得传递到指定回调函数的数码。

 

透过 HTML
协理IndexedDB是事务性的。在事情之外是无力回天执行命令或打开指针的。事务包罗如下类型:读/写作业、只读事务和快照事务。在本教程中,大家利用的是读/写作业。

 

第 1步:打开数据库

你必须先打开数据库,才能对其展开操作。 

 

[html]

html5rocks.indexedDB.db = null;    html5rocks.indexedDB.open =
function() {    var request = indexedDB.open(“todos”);    
 request.onsuccess = function(e) {      html5rocks.indexedDB.db =
e.target.result;      // Do some more stuff in a minute    };    
 request.onfailure = html5rocks.indexedDB.onerror;  };
 html5rocks.indexedDB.db = null;

 

html5rocks.indexedDB.open = function() {

  var request = indexedDB.open(“todos”);

 

  request.onsuccess = function(e) {

    html5rocks.indexedDB.db = e.target.result;

    // Do some more stuff in a minute

  };

 

  request.onfailure = html5rocks.indexedDB.onerror;

};我们已开拓名为“todos”的数据库,并已将其分配给html5rocks.indexedDB对象中的db变量。现在我们可以在全体课程中行使此变量来引用大家的数据库。

 

第 2步:创制对象存储

你不得不在“SetVersion”事务内成立对象存储。我还尚未介绍setVersion,那是一个卓殊首要的主意,那是代码中唯一可以供你创设对象存储和目录的地点。

 

[html]

html5rocks.indexedDB.open = function() {    var request =
indexedDB.open(“todos”,      “This is a description of the database.”);
     request.onsuccess = function(e) {      var v = “1.0”;    
 html5rocks.indexedDB.db = e.target.result;      var db =
html5rocks.indexedDB.db;      // We can only create Object stores in a
setVersion transaction;      if(v!= db.version) {        var setVrequest
= db.setVersion(v);          // onsuccess is the only place we can
create Object Stores        setVrequest.onfailure =
html5rocks.indexedDB.onerror;        setVrequest.onsuccess = function(e)
{          var store = db.createObjectStore(“todo”,            {keyPath:
“timeStamp”});            html5rocks.indexedDB.getAllTodoItems();      
 };      }        html5rocks.indexedDB.getAllTodoItems();    };    
 request.onfailure = html5rocks.indexedDB.onerror;  }
 html5rocks.indexedDB.open = function() {

  var request = indexedDB.open(“todos”,

    “This is a description of the database.”);

 

  request.onsuccess = function(e) {

    var v = “1.0”;

    html5rocks.indexedDB.db = e.target.result;

    var db = html5rocks.indexedDB.db;

    // We can only create Object stores in a setVersion transaction;

    if(v!= db.version) {

      var setVrequest = db.setVersion(v);

 

      // onsuccess is the only place we can create Object Stores

      setVrequest.onfailure = html5rocks.indexedDB.onerror;

      setVrequest.onsuccess = function(e) {

        var store = db.createObjectStore(“todo”,

          {keyPath: “timeStamp”});

 

        html5rocks.indexedDB.getAllTodoItems();

      };

    }

 

    html5rocks.indexedDB.getAllTodoItems();

  };

 

  request.onfailure = html5rocks.indexedDB.onerror;

}上述代码其实有为数不少效果。我们在
API中定义了“open”方法,调用此方法即可打开“todos”数据库。打开请求不是及时执行的,而是回到IDBRequest。假诺当前函数存在,则会调用indexedDB.open方法。那与大家普通指定异步回调的主意略有差别,可是我们在回调执行前,有时机向IDBRequest对象附加大家团结的监听器。

 

若是打开请求成功了,大家的
onsuccess回调就会执行。在此回调中,大家应反省数据库版本,假设与预期版本不符,则调用“setVersion”。

 

setVersion
是代码中唯一能让大家改变数据库结构的地方。在setVersion中,我们得以创制和删除对象存储,以及打造和删除索引。调用setVersion可回到IDBRequest对象,供大家在里头附加回调。借使成功了,大家就初阶创设对象存储。

 

经过对
createObjectStore单次调用创设对象存储。该方法会命名存储以及参数对象。参数对象非常关键,它可让您定义主要的可选属性。就大家而言,定义keyPath属性可让单个对象在仓储中兼有唯一性。本例中的该属性为“timeStamp”。objectStore中存储的各类对象都必须有“timeStamp”。

 

创办了目的存储后,我们调用 getAllTodoItems方法。

 

第 3步:向目的存储添加多少

咱俩要打造的是待办事项列表管理器,由此必要求可以向数据库中添加待办事项。方法如下:

 

[html] 

html5rocks.indexedDB.addTodo = function(todoText) {    var db =
html5rocks.indexedDB.db;    var trans = db.transaction([“todo”],
IDBTransaction.READ_WRITE, 0);    var store =
trans.objectStore(“todo”);    var request = store.put({      “text”:
todoText,      “timeStamp” : new Date().getTime()    });    
 request.onsuccess = function(e) {      // Re-render all the todo’s    
 html5rocks.indexedDB.getAllTodoItems();    };      request.onerror =
function(e) {      console.log(e.value);    };  };
 html5rocks.indexedDB.addTodo = function(todoText) {

  var db = html5rocks.indexedDB.db;

  var trans = db.transaction([“todo”], IDBTransaction.READ_WRITE, 0);

  var store = trans.objectStore(“todo”);

  var request = store.put({

    “text”: todoText,

    “timeStamp” : new Date().getTime()

  });

 

  request.onsuccess = function(e) {

    // Re-render all the todo’s

    html5rocks.indexedDB.getAllTodoItems();

  };

 

  request.onerror = function(e) {

    console.log(e.value);

  };

};addTodo方法格外简单,我们先是得到数据库对象的快捷引用,伊始化READ_WRITE事务,并得到我们对象存储的引用。

 

既然使用有权访问对象存储,大家就足以因而基础JSON
对象发出简短的put命令。请留心timeStamp属性,那是指标的绝无仅有密钥,并视作“keyPath”使用。put调用成功后,会触发onsuccess事件,然后大家就足以在显示屏上突显内容了。

 

第 4步:查询存储中的数据。

既然如此数据现已在数据库中了,大家就须要通过某种格局以有意义的艺术访问数据。幸运的是,这样的不二法门十分简单直接:

 

[html] 

html5rocks.indexedDB.getAllTodoItems = function() {    var todos =
document.getElementById(“todoItems”);    todos.innerHTML = “”;      var
db = html5rocks.indexedDB.db;    var trans = db.transaction([“todo”],
IDBTransaction.READ_WRITE, 0);    var store =
trans.objectStore(“todo”);      // Get everything in the store;    var
keyRange = IDBKeyRange.lowerBound(0);    var cursorRequest =
store.openCursor(keyRange);      cursorRequest.onsuccess = function(e) {
     var result = e.target.result;      if(!!result == false)      
 return;        renderTodo(result.value);      result.continue();    };
     cursorRequest.onerror = html5rocks.indexedDB.onerror;  };
 html5rocks.indexedDB.getAllTodoItems = function() {

  var todos = document.getElementById(“todoItems”);

  todos.innerHTML = “”;

 

  var db = html5rocks.indexedDB.db;

  var trans = db.transaction([“todo”], IDBTransaction.READ_WRITE, 0);

  var store = trans.objectStore(“todo”);

 

  // Get everything in the store;

  var keyRange = IDBKeyRange.lowerBound(0);

  var cursorRequest = store.openCursor(keyRange);

 

  cursorRequest.onsuccess = function(e) {

    var result = e.target.result;

    if(!!result == false)

      return;

 

    renderTodo(result.value);

    result.continue();

  };

 

  cursorRequest.onerror = html5rocks.indexedDB.onerror;

};请小心,本例中接纳的兼具那一个命令都是异步的,由此数据不是从事务内部再次来到的。

 

该代码可转变事务,并将对此数据的
keyRange搜索实例化。keyRange定义了俺们要从存储中查询的大约数据子集。假使存储的keyRange是数字时间戳,大家应将寻找的微小值设为0(时间原点后的别样时刻),那样就能回来所有数据。

 

现行我们有了工作、对要查询的囤积的引用以及要迭代的限量。剩下的办事就是开辟指针并附加“onsuccess”事件了。

 

结果会传送到对指针的成功回调,并在其间表现。对于每个结果只会启动一回回调,由此请务必持续迭代您需求的多少,以管教对结果对象调用“continue”。

 

第 4 步:展现对象存储中的数据

从目的存储中抓取了数量后,将对指针中的每个结果调用renderTodo方法。

 

[html] 

function renderTodo(row) {    var todos =
document.getElementById(“todoItems”);    var li =
document.createElement(“li”);    var a = document.createElement(“a”);  
 var t = document.createTextNode();    t.data = row.text;    
 a.addEventListener(“click”, function(e) {    
 html5rocks.indexedDB.deleteTodo(row.text);    });      a.textContent =
” [Delete]”;    li.appendChild(t);    li.appendChild(a);  
 todos.appendChild(li)  }  function renderTodo(row) {

  var todos = document.getElementById(“todoItems”);

  var li = document.createElement(“li”);

  var a = document.createElement(“a”);

  var t = document.createTextNode();

  t.data = row.text;

 

  a.addEventListener(“click”, function(e) {

    html5rocks.indexedDB.deleteTodo(row.text);

  });

 

  a.textContent = ” [Delete]”;

  li.appendChild(t);

  li.appendChild(a);

  todos.appendChild(li)

}对于某个指定的待办事项,大家只须求取得文本并为其创设用户界面(包含“删除”按钮,以便除去待办事项)。

 

第 5步:删除表格中的数据

[html] 

html5rocks.indexedDB.deleteTodo = function(id) {    var db =
html5rocks.indexedDB.db;    var trans = db.transaction([“todo”],
IDBTransaction.READ_WRITE, 0);    var store =
trans.objectStore(“todo”);      var request = store.delete(id);    
 request.onsuccess = function(e) {    
 html5rocks.indexedDB.getAllTodoItems();  // Refresh the screen    };  
   request.onerror = function(e) {      console.log(e);    };  };
 html5rocks.indexedDB.deleteTodo = function(id) {

  var db = html5rocks.indexedDB.db;

  var trans = db.transaction([“todo”], IDBTransaction.READ_WRITE, 0);

  var store = trans.objectStore(“todo”);

 

  var request = store.delete(id);

 

  request.onsuccess = function(e) {

    html5rocks.indexedDB.getAllTodoItems();  // Refresh the screen

  };

 

  request.onerror = function(e) {

    console.log(e);

  };

};正如将数据
put到目的存储中的代码一样,删除数据也很简短。启动一个政工,通过对象引用对象存储,然后通过对象的唯一ID发出delete命令。

 

第 6步:全体提到起来

在加载网页时,打开数据库并创设表格(如有须求),然后展现数据库中或许已存在的其他待办事项。

 

[html] 

function init() {    html5rocks.indexedDB.open(); // open displays the
data previously saved  }    window.addEventListener(“DOMContentLoaded”,
init, false);  function init() {

  html5rocks.indexedDB.open(); // open displays the data previously
saved

}

 

window.add伊芙ntListener(“DOMContentLoaded”, init,
false);那须求用到可将数据取出 DOM的函数,即
html5rocks.indexedDB.addTodo方法: 

 

[html] 

function addTodo() {    var todo = document.getElementById(‘todo’);    
 html5rocks.indexedDB.addTodo(todo.value);  

IndexedDB是HTML5中的新增效益。互连网数据库托管并留存在用户的浏览器内。只要让开发人员通过抬高的查询功用创制应用,就可以预感到…

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图