www.qjdy.com-奇迹赌场 > www.qjdy.com官网 > 前端的数据库:IndexedDB入门

原标题:前端的数据库:IndexedDB入门

浏览次数:145 时间:2019-10-19

前面一个的数据库: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

图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的唯人欢马叫性。为了求证那或多或少,想想多少个回顾电子邮件地址属性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事件。

图片 2

图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和华为部分扶植。就算那些列表的扶持者是欢腾的,但它从未报告全体传说。

图片 3

图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突显了正在编纂职分时的应用程序。

图片 4

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

图片 5

图5:职务列表

图片 6

图6:删除任务

图片 7

图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的名字到数组中。事务函数的第三个参数是三个情势。

借使事情央求可用,您就足以因此传递要求的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

图片 8

今日头条今日头条:@hop_ping 个人主页 · 小编的篇章 · 17

图片 9

本文由www.qjdy.com-奇迹赌场发布于www.qjdy.com官网,转载请注明出处:前端的数据库:IndexedDB入门

关键词: IndexedDB

上一篇:indexedDB 基本使用

下一篇:没有了