www.22138com「太阳集团游戏」太阳2007娱乐官方网址

欢迎更多朋友与我们www.22138com合作,太阳集团游戏是由安全软件管理软件整合而成的最新安全卫士,其实这是因为目前已经推出了太阳2007娱乐官方网址的新网址,带您体验至尊级享受!。

前端的数据库:IndexedDB入门

2019-04-26 02:11 来源:未知

前者的数据库: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的数据,呈现了数据库的组织

图片 1

图一:开拓者工具查看三个object store

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

设计指南

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的唯1性。为了表明这或多或少,想想多个归纳电子邮件地址属性Person对象。您可以配备你的store使用in-line键emailAddress,它能确定保证store(持久化对象中的数据)的唯1性。其余,out-of-line键通过单独于数据的值识别唯壹性。在那种景色下,你可以把out-of-line键比作八个整数值,它(整数值)在关周全据库中出任记录的主键。

图1展现了职分数据保存在职分的object store,它利用in-line键。在这几个案例中,键对应于对象的ID值。

听他们讲事务

分化于一些观念的关周到据库的落到实处,每三个对数据库操作是在三个事情的光景文中实施的。事务限制二回影响三个或四个object stores,你通过传播一个object store名字的数组到开创专门的学业限制的函数来定义。

创办工作的第二个参数是业务情势。当呼吁2个事务时,必须调节是依据只读依旧读写情势请求访问。事务是财富密集型的,所以假若你不供给改造data store中的数据,你只供给以只读格局对object stores集合进行呼吁访问。

清单2示范了什么样运用方便的形式创立二个工作,并在那片作品的 Implementing Database-Specific Code 部分开始展览了详细座谈。

依靠请求

以致于这里,有四个往往出现的宗旨,您只怕已经注意到。对数据库的历次操作,描述为经过二个呼吁张开数据库,访问叁个object store,再持续。IndexedDB API天生是依据请求的,这也是API异步天性提醒。对于你在数据库推行的每回操作,你必须首先为那个操作创制三个伸手。当呼吁落成,你能够响应由请求结果发生的风浪和不当。

正文完毕的代码,演示了怎么着利用请求展开数据库,创设三个政工,读取object store的内容,写入object store,清空object store。

开拓数据库的伸手生命周期

IndexedDB使用事件生命周期管理数据库的开辟和布局操作。图二示范了贰个开采的呼吁在一定的情形下发生upgrade need事件。

图片 2

图贰:IndexedDB张开请求的生命周期

有着与数据库的相互早先于二个开发的伏乞。试图展开数据库时,您必须传递二个被呼吁数据库的本子号的整数值。在开采请求时,浏览器比较你传入的用来展开请求的版本号与实际数据库的版本号。纵然所请求的版本号高于浏览器中当前的版本号(也许今后未曾存在的数据库),upgrade needed事件触发。在uprade need事件之间,你有空子通过抬高或移除stores,键和索引来垄断object stores。

只要所请求的数据库版本号和浏览器的当前版本号壹致,也许进级过程一气浑成,1个开采的数据库将回来给调用者。

荒唐冒泡

本来,有时候,请求或许不会按预期实现。IndexedDB API通过荒谬冒泡效果来救助追踪和保管不当。假如二个一定的伸手蒙受错误,你能够尝试在央求对象上管理错误,或然您可以允许错误通过调用栈冒泡向上传递。那些冒泡个性,使得你不须求为每种请求落成特定错误管理操作,而是可以选拔只在二个越来越高端别上增加错误管理,它给您2个时机,保持您的错误管理代码简洁。本文中落成的事例,是在二个高等别管理错误,以便越来越细粒度操作产生的其它不当冒泡到通用的错误管理逻辑。

浏览器帮助

莫不在支付Web应用程序最入眼的题目是:“浏览器是或不是帮忙本人想要做的?“就算浏览器对IndexedDB的协助在继承巩固,采纳率并不是大家所企盼的那么广泛。图三体现了caniuse.com网站的告知,扶助IndexedDB的为66%多一丢丢。最新版本的银狐,Chrome,Opera,Safar,iOS Safari,和Android完全援助IndexedDB,Internet Explorer和华为部分帮忙。就算那个列表的维护者是冲动的,但它没有报告全体逸事。

图片 3

图3:浏览器对IndexedDB的援救,来自caniuse.com

除非丰硕新本子的Safari和iOS Safari 协理IndexedDB。据caniuse.com呈现,那只占大致0.0壹%的伍洲浏览器接纳。IndexedDB不是2个您以为能够理所当然得到帮忙的当代Web API,可是你将高速会这么以为。

另一种选拔

浏览器援助地点数据库并不是从IndexedDB才开端达成,它是在WebSQL兑现之后的壹种新格局。类似IndexedDB,WebSQL是1个客户端数据库,但它看做贰个关周到据库的贯彻,使用结构化查询语言(SQL)与数据库通信。WebSQL的历史充满了弯曲,但底线是不曾主流的浏览器厂家对WebSQL继续援救。

若果WebSQL实际上是三个扬弃的技艺,为何还要提它吗?风趣的是,WebSQL在浏览器里获取巩固的支持。Chrome, Safari, iOS Safari, and Android 浏览器都帮衬。其余,并不是那几个浏览器的新星版本才提供支撑,好些个这几个最新最棒的浏览器此前的版本也足以支撑。有意思的是,借使您为WebSQL增添匡助来扶助IndexedDB,你突然意识,许多浏览器商家和本子成为支撑浏览器内置数据库的某种化身。

因而,假使你的应用程序真正需求一个客户端数据库,你想要达到的最高端其他选用恐怕,当IndexedDB不可用时,只怕你的应用程序大概看起来须要采纳选取WebSQL来支撑客户端数据架构。就算文书档案数据库和关周详据库管理数占有拨云见日的歧异,但万1你有不易的肤浅,就可以应用本地数据库构建一个应用程序。

IndexedDB是还是不是适合本人的应用程序?

以后最根本的题目:“IndexedDB是还是不是合乎作者的应用程序?“像过去一样,答案是早晚的:“视情状而定。“首先当您筹算在客户端保存数据时,你会记挂HTML5本土存款和储蓄。本地存款和储蓄获得大规模浏览器的援救,有十分便于使用的API。轻易有其优势,但其劣势是无能为力支撑复杂的探寻攻略,存款和储蓄大量的数额,并提供专门的学业帮忙。

IndexedDB是叁个数据库。所以,当您想为客户端做出决定,思索你哪些在服务端选择一个持久化介质的数据库。你或者会问自身某些主题素材来帮衬调节客户端数据库是不是合乎您的应用程序,包涵:

  • 你的用户通过浏览器访问您的应用程序,(浏览器)辅助IndexedDB API吗 ?
  • 你须要仓储大批量的数量在客户端?
  • 你供给在一个巨型的数量集合中赶快稳固单个数办事处?
  • 您的架构在客户端须要工作协助呢?

假若你对中间的其余难点答疑了“是的”,很有一点都不小可能率,IndexedDB是你的应用程序的七个很好的候选。

使用IndexedDB

当今,你曾经有机会熟习了1部分的完全概念,下一步是开首兑现基于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开端工作。

使用概述

在本教程中,您将学习怎么着创制1个运用IndexedDB存款和储蓄数据的模块化JavaScript应用程序。为了打探应用程序是什么样行事的,参考图四,它讲述了任务应用程序处于空白状态。从那里您可感觉列表加多新职分。图伍显得了录入了多少个使命到系统的画面。图陆出示怎么删除二个任务,图七显示了正在编纂职务时的应用程序。

图片 4

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

图片 5

图伍:职务列表

图片 6

图陆:删除职分

图片 7

图7:编辑职务
近来您纯熟的应用程序的效用,下一步是始于为网址铺设基础。

铺设基础

以此事例从贯彻如此一个模块开端,它担负从数据库读取数据,插入新的对象,更新现存对象,删除单个对象和提供在2个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));

用这么的构造,能够使那一个应用程序的全体逻辑封装在1个名称叫app的单对象上。其余,数据库相关的代码在3个叫作db的app子对象上。

以此模块的代码应用IIFE,通过传递window对象来保管模块的妥善限制。使用use strict确认保障那么些函数的代码函数是依照(javascript严峻方式)严峻编写翻译规则。db对象作为与数据库交互的具备函数的基本点容器。最终,window对象检查app的实例是还是不是留存,假使存在,模块使用当前实例,若是不存在,则创造二个新目标。一旦app对象成功重回或创办,db对象附加到app对象。

正文的别的部分将代码加多到db对象内(在implementation here会评价),为应用程序提供一定于数据库的逻辑。由此,如您所见本文后边的片段中定义的函数,想想父db对象活动,但全体其它职能都以db对象的分子。完整的数据库模块列表见清单二。

Implementing Database-Specific Code

对数据库的各种操作关联着一个先决条件,即有3个张开的数据库。当数据库正在被展开时,通过检查数据库版本来判断数据库是还是不是供给其它退换。上面包车型客车代码突显了模块怎么着跟踪当前版本,object store名、某成员(保存了假若数据库展开请求达成后的数据库当前实例)。

JavaScript

version: 1, objectStoreName: 'tasks', instance: {},

1
2
3
version: 1,
objectStoreName: 'tasks',
instance: {},

在那边,数据库展开请求发生时,模块请求版本一数据库。若是数据库不存在,也许版本小于壹,upgrade needed事件在开拓请求完毕前触发。那几个模块被安装为只利用2个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成员)来创制。

模块的下2个功用是用来捕获错误,错误在模块分化的央求创造时冒泡。

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,您能够很轻便地观察其余不当(当她们产生时)。当你希图在生养条件使用那个模块,您要求在这几个函数中达成部分错误管理代码来和您的应用程序的上下文打交道。

现行反革命基础实现了,那1节的其他部分将演示怎么样贯彻对数据库推行一定操作。第2个必要检查的函数是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的名目和您想利用的数据库版本号。

假如请求的实例可用,第3步要拓展的行事是设置错误管理程序和升高函数。记住,当数据库被展开时,如若脚本请求比浏览器里更加高版本的数据库(也许一旦数据库不设有),晋级函数运转。但是,若是请求的数据库版本相配当前数据库版本同时未有不当,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,可是1旦您必要在事情中操作三个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事件管理程序须要设置在回调函数上,来告诉调用脚本,壹切进展顺遂。

下壹节的代码在清单一所示。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获得全部数据,下2个亟需贯彻的函数是负担访问单个记录。

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值无法分析成整数的荒谬例子的回调,但为了引导原因,代码示例是假意的。

1旦id值能担保转换到多少个整数,数据库被张开,1个可写的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的多少个可写实例。1旦store可用,二个新的伸手通过调用clear函数来创建。1旦clear操作成功,回调函数被推行。

实行用户分界面特定代码

当今具有特定于数据库的代码被封装在app.db模块中,用户界面特定代码能够运用此模块来与数据库交互。用户分界面特定代码的总体清单(index.ui.js)能够在清单3中获取,完整的(index.html)页面的HTML源代码能够在清单四中拿走。

结论

趁着应用程序的急需的滋长,你会开掘在客户端高效存款和储蓄大批量的数目的优势。IndexedDB是足以在浏览器中一向使用且援救异步事务的文书档案数据库落成。即便浏览器的支撑大概否保险,但在安妥的事态下,集成IndexedDB的Web应用程序具备强有力的客户端数据的拜会才具。

在很多景况下,全体针对IndexedDB编写的代码是天生基于请求和异步的。官方正式有同步API,但是那种IndexedDB只适合web worker的上下文中使用。那篇小说揭橥时,还未曾浏览器落成的协同格式的IndexedDB API。

早晚要保管代码在别的函数域外对厂家特定的indexedDB, IDBTransaction, and IDBKeyRange实例进行了规范化且使用了严峻格局。那允许你避免浏览器错误,当在strict mode下解析脚本时,它不会同意你对那多少个对象重新赋值。

您不能够不确认保证只传递正整数的本子号给数据库。传递到版本号的小数值会四舍5入。因而,假设您的数据库目前版本一,您希图访问1.二版本,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

图片 8

网易新浪:@hop_ping 个人主页 · 作者的稿子 · 17

图片 9

TAG标签: www.22138com IndexedDB
版权声明:本文由太阳集团发布于太阳2007娱乐官方网址,转载请注明出处:前端的数据库:IndexedDB入门