OLD | NEW |
---|---|
1 --- | 1 --- |
2 layout: default | 2 layout: default |
3 title: "Use IndexedDB" | 3 title: "Use IndexedDB" |
4 description: "Use IndexedDB for persistence and offline capability for your app. " | 4 description: "Use IndexedDB for persistence and offline capability for your app. " |
5 has-permalinks: true | 5 has-permalinks: true |
6 tutorial: | 6 tutorial: |
7 id: indexeddb | 7 id: indexeddb |
8 next: index.html | 8 next: index.html |
Kathy Walrath
2013/07/26 19:33:27
ew, do we really have to say "index.html"? it mess
mem
2013/07/26 20:36:32
Done.
| |
9 next-title: "A Game of Darts" | 9 next-title: "A Game of Darts" |
10 prev: forms | 10 prev: forms/ |
11 prev-title: "Get Input from a Form" | 11 prev-title: "Get Input from a Form" |
12 --- | 12 --- |
13 | 13 |
14 {% capture whats_the_point %} | 14 {% capture whats_the_point %} |
15 | 15 |
16 * IndexedDB is a new standard for client-side storage in modern web browsers. | 16 * IndexedDB is a new standard for client-side storage in modern web browsers. |
17 * Client-side storage provides persistence, offline capability, | 17 * Client-side storage provides persistence, offline capability, |
18 and other advantages. | 18 and other advantages. |
19 * IndexedDB lets you store significant amounts of structured data. | 19 * IndexedDB lets you store significant amounts of structured data. |
20 * Indices allow for high performance searches. | 20 * Indices allow for high performance searches. |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
78 Check | 78 Check |
79 <a href="http://caniuse.com/#feat=indexeddb" | 79 <a href="http://caniuse.com/#feat=indexeddb" |
80 target="_blank">caniuse.com</a> | 80 target="_blank">caniuse.com</a> |
81 for up-to-date information. | 81 for up-to-date information. |
82 Your app can check programmatically | 82 Your app can check programmatically |
83 if the current platform supports IndexedDB | 83 if the current platform supports IndexedDB |
84 and adjust accordingly. | 84 and adjust accordingly. |
85 </aside> | 85 </aside> |
86 | 86 |
87 This target shows you how to use | 87 This target shows you how to use |
88 <a href="http://api.dartlang.org/dart_indexed_db.html" | 88 <a href="https://api.dartlang.org/dart_indexed_db.html" |
89 target="_blank">dart:indexed_db</a> | 89 target="_blank">dart:indexed_db</a> |
90 to store data to and retrieve data from the browser's IndexedDB. | 90 to store data to and retrieve data from the browser's IndexedDB. |
91 | 91 |
92 * [Run the app](#run-the-app) | 92 * [Run the app](#run-the-app) |
93 * [About the app: The basics](#the-basics) | 93 * [About the app: The basics](#the-basics) |
94 * [Details about IndexedDB](#details-about-indexeddb) | 94 * [Details about IndexedDB](#details-about-indexeddb) |
95 * [Importing the IndexedDB library](#import-indexeddb) | 95 * [Importing the IndexedDB library](#import-indexeddb) |
96 * [Checking for IndexedDB support](#checking-indexeddb) | 96 * [Checking for IndexedDB support](#checking-indexeddb) |
97 * [Creating and opening a database](#opening-indexeddb) | 97 * [Creating and opening a database](#opening-indexeddb) |
98 * [Creating an object store](#creating-object-store) | 98 * [Creating an object store](#creating-object-store) |
(...skipping 22 matching lines...) Expand all Loading... | |
121 <a href="index.html#run-the-app">this page</a>. | 121 <a href="index.html#run-the-app">this page</a>. |
122 The milestone you created still exists | 122 The milestone you created still exists |
123 because the app stored it in an IndexedDB in the browser. | 123 because the app stored it in an IndexedDB in the browser. |
124 | 124 |
125 Use the minus (**-**) button to the right of a milestone | 125 Use the minus (**-**) button to the right of a milestone |
126 to delete that milestone. | 126 to delete that milestone. |
127 Use the **Clear** button to delete all the milestones. | 127 Use the **Clear** button to delete all the milestones. |
128 | 128 |
129 <iframe class="running-app-frame" | 129 <iframe class="running-app-frame" |
130 style="height:400px;width:600px;" | 130 style="height:400px;width:600px;" |
131 src="http://dart-lang.github.com/dart-tutorials-samples/web/target11/cou nt_down/web/out/count_down.html"> | 131 src="http://dart-lang.github.io/dart-tutorials-samples/web/target11/coun t_down/web/out/count_down.html"> |
132 </iframe> | 132 </iframe> |
133 | 133 |
134 You can find the complete source code for this sample on github at | 134 You can find the complete source code for this sample on github at |
135 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/tar get11/count_down" target="_blank">count_down</a>. | 135 <a href="https://github.com/dart-lang/dart-tutorials-samples/tree/master/web/tar get11/count_down" target="_blank">count_down</a>. |
136 | 136 |
137 ###Using developer tools to look at the database | 137 ###Using developer tools to look at the database |
138 | 138 |
139 You can use the browser's developer tools | 139 You can use the browser's developer tools |
140 to explore the IndexedDB databases used by your apps. | 140 to explore the IndexedDB databases used by your apps. |
141 In Chrome, select **View > Developer > Developer Tools**, | 141 In Chrome, select **View > Developer > Developer Tools**, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
183 The View-model queries the Model upon initialization | 183 The View-model queries the Model upon initialization |
184 and uses Web UI data-bindings to keep the View in sync. | 184 and uses Web UI data-bindings to keep the View in sync. |
185 Also, it uses Timer events to trigger updates in the Model. | 185 Also, it uses Timer events to trigger updates in the Model. |
186 | 186 |
187 ###The libraries used by the count_down app | 187 ###The libraries used by the count_down app |
188 | 188 |
189 The count_down app uses the following libraries: | 189 The count_down app uses the following libraries: |
190 | 190 |
191 | Library | Description | | 191 | Library | Description | |
192 |---|---| | 192 |---|---| |
193 | <a href="http://api.dartlang.org/dart_indexed_db.html" target="_blank">dart:in dexed_db</a> | Save data into an indexed database for persistence and offline ca pability | | 193 | <a href="https://api.dartlang.org/dart_indexed_db.html" target="_blank">dart:i ndexed_db</a> | Save data into an indexed database for persistence and offline c apability | |
194 | <a href="http://api.dartlang.org/dart_async.html" target="_blank">dart:async</ a> | Perform tasks asynchronously | | 194 | <a href="https://api.dartlang.org/dart_async.html" target="_blank">dart:async< /a> | Perform tasks asynchronously | |
195 | <a href="http://api.dartlang.org/dart_core.html" target="_blank">dart:core</a> | Use DateTime and Duration to manage time-related tasks | | 195 | <a href="https://api.dartlang.org/dart_core.html" target="_blank">dart:core</a > | Use DateTime and Duration to manage time-related tasks | |
196 | <a href="http://pub.dartlang.org/packages/web_ui" target="_blank">package:web_ ui</a> | Create UIs with data-binding and web components. | | 196 | <a href="https://pub.dartlang.org/packages/web_ui" target="_blank">package:web _ui</a> | Create UIs with data-binding and web components. | |
197 {: .table } | 197 {: .table } |
198 | 198 |
199 This target explains the Dart API for IndexedDB used by the count_down app. | 199 This target explains the Dart API for IndexedDB used by the count_down app. |
200 In addition, this target covers some interesting | 200 In addition, this target covers some interesting |
201 API related to dates, times, and timers. | 201 API related to dates, times, and timers. |
202 | 202 |
203 <aside class="alert" markdown="1"> | 203 <aside class="alert" markdown="1"> |
204 <strong>Note:</strong> | 204 <strong>Note:</strong> |
205 This target does not cover Futures or Web UI. | 205 This target does not cover Futures or Web UI. |
206 For information about Futures, | 206 For information about Futures, |
207 see | 207 see |
208 <a href="/articles/using-future-based-apis/">Using Future Based APIs</a> | 208 <a href="/articles/using-future-based-apis/">Using Future Based APIs</a> |
209 and | 209 and |
210 <a href="/articles/futures-and-error-handling/">Futures and Error Handling</a>. | 210 <a href="/articles/futures-and-error-handling/">Futures and Error Handling</a>. |
211 For information about Web UI, | 211 For information about Web UI, |
212 check out the relevant recipes in the | 212 check out the relevant recipes in the |
213 <a href="/docs/cookbook/"> | 213 <a href="/docs/cookbook/"> |
214 <i class="icon-food"> </i> Dart Cookbook</a> | 214 <i class="icon-food"> </i> Dart Cookbook</a> |
215 or read the Web UI tutorials in | 215 or read the Web UI tutorials in |
216 Targets <a href="/docs/tutorials/web-ui">6</a>, | 216 Targets <a href="/docs/tutorials/web-ui/">6</a>, |
217 <a href="/docs/tutorials/templates">7</a>, | 217 <a href="/docs/tutorials/templates/">7</a>, |
218 <a href="/docs/tutorials/custom-elements">8</a>. | 218 <a href="/docs/tutorials/custom-elements/">8</a>. |
219 | 219 |
220 </aside> | 220 </aside> |
221 | 221 |
222 ##Details about IndexedDB | 222 ##Details about IndexedDB |
223 | 223 |
224 Some important facts you need to know about IndexedDB: | 224 Some important facts you need to know about IndexedDB: |
225 | 225 |
226 * Each origin (host, protocol, and port) has its own set of databases. | 226 * Each origin (host, protocol, and port) has its own set of databases. |
227 A unique name identifies each database within an origin. | 227 A unique name identifies each database within an origin. |
228 IndexedDB has a same-origin policy, | 228 IndexedDB has a same-origin policy, |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
417 All the countdown milestones are stored and retrieved | 417 All the countdown milestones are stored and retrieved |
418 in this object store. | 418 in this object store. |
419 | 419 |
420 The code sets `autoIncrement` on the object store to true. | 420 The code sets `autoIncrement` on the object store to true. |
421 When autoIncrement is true, | 421 When autoIncrement is true, |
422 the database generates unique, primary keys for you, | 422 the database generates unique, primary keys for you, |
423 which saves you the trouble of doing so. | 423 which saves you the trouble of doing so. |
424 | 424 |
425 Finally, `_initializeDatabase` creates an index. | 425 Finally, `_initializeDatabase` creates an index. |
426 | 426 |
427 ##Using an index | 427 ##Using a name index |
428 | 428 |
429 An index provides a lookup table. | 429 An index provides a lookup table. |
430 You can associate a primary key with a field in the stored objects. | 430 You can associate a primary key with a field in the stored objects. |
431 In the example, | 431 In the example, |
432 the index associates a primary key with the milestoneName field. | 432 the index associates a primary key with the milestoneName field. |
433 | 433 |
434  | 434  |
435 | 435 |
436 Using an index provides two benefits: | 436 Using an index provides two benefits: |
437 | 437 |
(...skipping 19 matching lines...) Expand all Loading... | |
457 * unique, a boolean value. | 457 * unique, a boolean value. |
458 When true, the index ensures that the milestone name is unique. | 458 When true, the index ensures that the milestone name is unique. |
459 In the count_down app, | 459 In the count_down app, |
460 if you try to add a milestone with the same name as another, | 460 if you try to add a milestone with the same name as another, |
461 it is this index that causes the add() to fail. | 461 it is this index that causes the add() to fail. |
462 | 462 |
463 ##Using transactions {#using-transactions} | 463 ##Using transactions {#using-transactions} |
464 | 464 |
465 All database operations must be performed | 465 All database operations must be performed |
466 within a | 466 within a |
467 <a href="http://api.dartlang.org/dart_indexedDb/Transaction.html" target="_blank ">Transaction</a>. | 467 <a href="https://api.dartlang.org/dart_indexedDb/Transaction.html" target="_blan k">Transaction</a>. |
468 | 468 |
469 <aside class="alert" markdown="1"> | 469 <aside class="alert" markdown="1"> |
470 <strong>Important: About the life-cycle of a transaction</strong> | 470 <strong>Important: About the life-cycle of a transaction</strong> |
471 | 471 |
472 The life-cycle of a transaction is as follows: | 472 The life-cycle of a transaction is as follows: |
473 | 473 |
474 * Open a transaction. | 474 * Open a transaction. |
475 * Place requests on the transaction and register callbacks. | 475 * Place requests on the transaction and register callbacks. |
476 * When there are no more requests | 476 * When there are no more requests |
477 and the last callback finishes, the transaction completes. | 477 and the last callback finishes, the transaction completes. |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
657 return cursors.length.then((_) { | 657 return cursors.length.then((_) { |
658 return milestones.length; | 658 return milestones.length; |
659 }); | 659 }); |
660 } | 660 } |
661 {% endprettify %} | 661 {% endprettify %} |
662 | 662 |
663 Because getting records does not modify the database, | 663 Because getting records does not modify the database, |
664 this transaction is readonly. | 664 this transaction is readonly. |
665 | 665 |
666 You can use a | 666 You can use a |
667 <a href="http://api.dartlang.org/dart_indexedDb/Cursor.html" target="_blank">Cur sor</a> | 667 <a href="https://api.dartlang.org/dart_indexedDb/Cursor.html" target="_blank">Cu rsor</a> |
668 object to step through the records in the database one by one, | 668 object to step through the records in the database one by one, |
669 creating a Milestone object for each. | 669 creating a Milestone object for each. |
670 The object store uses a stream to fire an event for each record | 670 The object store uses a stream to fire an event for each record |
671 retrieved from the database. | 671 retrieved from the database. |
672 By listening on the stream, | 672 By listening on the stream, |
673 your code can be notified for each record read. | 673 your code can be notified for each record read. |
674 The count_down app creates a corresponding Milestone object | 674 The count_down app creates a corresponding Milestone object |
675 in the internal list in memory for each database record retrieved. | 675 in the internal list in memory for each database record retrieved. |
676 | 676 |
677 Open a cursor on a transaction's object store with `openCursor`. | 677 Open a cursor on a transaction's object store with `openCursor`. |
(...skipping 11 matching lines...) Expand all Loading... | |
689 | 689 |
690 The openCursor() method returns a stream on which you can listen for events. | 690 The openCursor() method returns a stream on which you can listen for events. |
691 Here, | 691 Here, |
692 the stream is a broadcast stream, | 692 the stream is a broadcast stream, |
693 so the app can listen both for read events | 693 so the app can listen both for read events |
694 and for a final count of records retrieved. | 694 and for a final count of records retrieved. |
695 | 695 |
696 For each record retrieved from the database, | 696 For each record retrieved from the database, |
697 an event fires and the callback function is called. | 697 an event fires and the callback function is called. |
698 A | 698 A |
699 <a href="http://api.dartlang.org/dart_indexedDb/CursorWithValue.html" target="_b lank">CursorWithValue</a> | 699 <a href="https://api.dartlang.org/dart_indexedDb/CursorWithValue.html" target="_ blank">CursorWithValue</a> |
700 object, named `cursor` in this example, | 700 object, named `cursor` in this example, |
701 is passed to the callback function. | 701 is passed to the callback function. |
702 Use `cursor.key` to get the key for the record just retrieved. | 702 Use `cursor.key` to get the key for the record just retrieved. |
703 Use `cursor.value` to get the value for that record. | 703 Use `cursor.value` to get the value for that record. |
704 | 704 |
705 The _loadFromDB method returns a Future that returns the length of the stream. | 705 The _loadFromDB method returns a Future that returns the length of the stream. |
706 | 706 |
707 ##Other resources | 707 ##Other resources |
708 | 708 |
709 <ul> | 709 <ul> |
(...skipping 16 matching lines...) Expand all Loading... | |
726 ###What next? | 726 ###What next? |
727 | 727 |
728 Check out our | 728 Check out our |
729 <a href="/codelabs/web-ui-writer/index.html" target="_blank"><i class="icon-beak er"> </i>Codelab</a>; | 729 <a href="/codelabs/web-ui-writer/index.html" target="_blank"><i class="icon-beak er"> </i>Codelab</a>; |
730 it uses LocalStorage instead of IndexedDB to store data in the client. | 730 it uses LocalStorage instead of IndexedDB to store data in the client. |
731 Try converting it to use IndexedDB. | 731 Try converting it to use IndexedDB. |
732 | 732 |
733 {% endcapture %} | 733 {% endcapture %} |
734 | 734 |
735 {% include tutorial.html %} | 735 {% include tutorial.html %} |
OLD | NEW |