>

前面一个的数据库,长远深入分析HTML5中的Index

- 编辑:至尊游戏网站 -

前面一个的数据库,长远深入分析HTML5中的Index

前者的数据库:IndexedDB入门

2014/12/27 · 未分类 · IndexedDB

本文由 伯乐在线 - cucr 翻译,黄利民 校稿。未经许可,禁绝转发!
塞尔维亚(Serbia)语出处:www.codemag.com。接待加入翻译组。

应用程序必要多少。对绝大非常多Web应用程序来讲,数据在服务器端协会和保管,客商端通过互联网乞请获取。随着浏览器变得进一步有力量,由此可选择在浏览器存款和储蓄和调整应用程序数据。

正文向你介绍名称为IndexedDB的浏览器端文书档案数据库。使用lndexedDB,你能够经过惯于在劳务器端数据库差少之甚少同样的办法开创、读取、更新和删除大量的笔录。请使用本文中可工作的代码版本去感受,完整的源代码能够经过GitHub库找到。

读到本学科的终极时,你将熟知IndexedDB的基本概念甚至怎么样落成八个使用IndexedDB实施总体的CRUD操作的模块化JavaScript应用程序。让大家有一点点亲密IndexedDB并最早吧。

什么是IndexedDB

诚如的话,有二种不一样品种的数据库:关系型和文书档案型(也称为NoSQL或对象)。关周密据库如SQL Server,MySQL,Oracle的数量存储在表中。文书档案数据库如MongoDB,CouchDB,Redis将数据集作为个体对象存款和储蓄。IndexedDB是四个文档数据库,它在一起内放置浏览器中的三个沙盒情状中(强制依照(浏览器)同源战略)。图1展现了IndexedDB的多少,呈现了数据库的布局

图片 1

图1:开垦者工具查看二个object store

总体的IndexedDB API请参谋完整文书档案

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

这篇小说重要介绍了深切分析HTML第55中学的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. };   
  8.     
  9. request.onerror = function(e) {   
  10. alert("Unable to add the information.");    
  11. }   
  12.     
  13. }  

在此以前大家在数据库中做其他的CRUD操作(读,写,修改),必需选拔职业。 该transaction()方法是用来钦命大家想要进行事务管理的对象存款和储蓄。 transaction()方法接受3个参数(第一个和第七个是可选的)。 第贰个是我们要拍卖的对象存款和储蓄的列表,第叁个钦命大家是还是不是要只读/读写,第2个是本子变化。
 
从表中读取数据 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. }  

大家要将指标的key帕特h作为参数字传送递给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事务管理。可是结果就区别

图片 2

测试的时候b.html中大概不会立马有出口,因为indexedDB正忙着管理a.html东西,b.html事务丢在了业务丢队列中等待。不过无论如何,输出结果也不会是1那么些值。因为indexedDB的矮小处理单位是事情,并不是localStorage那样以表明式为单位。那样要是把lock和unlock之间供给管理的事物放入二个作业中就可以兑现。其余,浏览器对indexedDB的扶助不比localStorage,所以接纳时还得记挂浏览器宽容。

那篇小说首要介绍了浓郁分析HTML5中的IndexedDB索引数据库,蕴含事务锁等基本功用的相关使...

陈设标准

IndexedDB的架构很像在一些风行的劳务器端NOSQL数据库完结中的设计规范类型。面向对象数据通过object stores(对象酒店)进行长久化,全部操作基于诉求同反常间在事情限制内实行。事件生命周期让你可以见到支配数据库的配置,错误通过荒谬冒泡来使用API管理。

目的酒店

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值。

基于事务

不相同于一些思想的关周密据库的落到实处,每一个对数据库操作是在叁个作业的前后文中实施的。事务限制二遍影响二个或四个object stores,你通过传播三个object store名字的数组到创设工作限制的函数来定义。

创建筑工程作的第一个参数是事情情势。当呼吁一个事务时,必需调控是依据只读照旧读写形式央求访问。事务是财富密集型的,所以只要您无需改动data store中的数据,你只需求以只读形式对object stores集合实行呼吁访谈。

清单2演示了什么样利用合适的情势开创二个业务,并在此片文章的 Implementing Database-Specific Code 部分开展了详实批评。

听别人讲诉求

直到这里,有一个反复出现的核心,您恐怕曾经注意到。对数据库的每一次操作,描述为经过二个央求打开数据库,访谈一个object store,再持续。IndexedDB API天生是依据乞请的,那也是API异步天性提示。对于你在数据库实践的历次操作,你必得首先为这几个操作创制三个呼吁。当呼吁达成,你能够响应由要求结果产生的轩然大波和谬误。

正文完毕的代码,演示了什么利用央浼展开数据库,创立一个业务,读取object store的内容,写入object store,清空object store。

开发数据库的伏乞生命周期

IndexedDB使用事件生命周期管理数据库的开垦和配备操作。图2示范了贰个开垦的诉求在大势所趋的条件下发出upgrade need事件。

图片 3

图2:IndexedDB展开要求的生命周期

抱有与数据库的互相伊始于三个开垦的央浼。试图展开数据库时,您必得传递多少个被呼吁数据库的版本号的整数值。在打开乞求时,浏览器比较你传入的用于展开乞求的版本号与实际数据库的版本号。如果所哀告的版本号高于浏览器中当前的版本号(大概未来未有存在的数据库),upgrade needed事件触发。在uprade need事件之间,你有空子通过抬高或移除stores,键和索引来操纵object stores。

固然所央求的数据库版本号和浏览器的脚下版本号相同,大概晋级历程做到,三个展开的数据库将回到给调用者。

荒唐冒泡

当然,一时候,央浼也许不会按预期完毕。IndexedDB API通过荒谬冒泡效果来扶助追踪和治本八花九裂。若是三个一定的恳求遭受错误,你能够品尝在央求对象上管理错误,大概您能够允许错误通过调用栈冒泡向上传递。那么些冒泡天性,使得你不需求为各类央求完结特定错误管理操作,而是能够采取只在贰个越来越高等别上加多错误管理,它给您贰个机会,保持您的错误管理代码简洁。本文中达成的事例,是在二个高档别管理错误,以便更加细粒度操作产生的另外不当冒泡到通用的错误处理逻辑。

浏览器援救

只怕在支付Web应用程序最要害的主题素材是:“浏览器是或不是协理作者想要做的?“固然浏览器对IndexedDB的协助在后续进步,选取率并非大家所希望的那么普及。图3出示了caniuse.com网址的告知,帮助IndexedDB的为66%多一小点。最新版本的银狐,Chrome,Opera,Safar,iOS Safari,和Android完全协理IndexedDB,Internet Explorer和Nokia部分扶持。即使这几个列表的拥护者是快乐的,但它从未报告全部故事。

图片 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是不是符合自身的应用程序?

明日最根本的主题素材:“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存款和储蓄数据的模块化JavaScript应用程序。为了打探应用程序是何等职业的,参谋图4,它描述了职分应用程序处于空白状态。从这里你可以为列表加多新职分。图5来得了录入了几个职分到系统的镜头。图6浮现怎么删除多少个职务,图7展现了正在编写制定职责时的应用程序。

图片 5

图4:空白的天职应用程序

图片 6

图5:职责列表

图片 7

图6:删除职分

图片 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。

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的名字到数组中。事务函数的第1个参数是一个形式。

假若事情央求可用,您就能够通过传递需求的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的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 收藏 评论

至于我:cucr

图片 9

博客园果壳网:@hop_ping 个人主页 · 作者的篇章 · 17

图片 10

本文由软件综合发布,转载请注明来源:前面一个的数据库,长远深入分析HTML5中的Index