使用 Dexie 和 Svelte 从 IndexedDB 检索值

查克莫斯特

我不明白如何使用 Dexie 从 IndexedDB 获取值。数据库在检查工具的“应用程序”选项卡中都很好。完全是新手,请谅解。

我的 db.js

import Dexie from "dexie";

export const db = new Dexie("myDatabase");
db.version(2).stores({
  history: "++id, daterange, days",
  storage: "id, name, value"
});

db.on("populate", function () {
  db.storage.add({
    id: 0,
    name: "total",
    value: 20
  });
  db.storage.add({
    id: 1,
    name: "left",
    value: 20
  });
});
db.open();

App.svelte

<script>
  import Counter from "./src/Counter.svelte";
  import New from "./src/New.svelte";
  import History from "./src/History.svelte";
  import { liveQuery } from "dexie";
  import { db } from "./src/db";

  let total = liveQuery(() =>
    db.storage
      .where("name")
      .equals("total")
      .value.then(function(a) {
        totals = a;
      })
  );

  let left = 25;
</script>

<style>
  main {
    width: 100%;
  }
</style>

<main>
    <Counter daysLeft={left} daysMax={total}/>
    <New />
    <History />
</main>

无论我尝试什么,使用outputdaysMax={total}类似的对象我只想从 db 中获取,如 db.js 中所示:undefined[object Object][Dexie object Object]20

db.on("populate", function () {
  db.storage.add({
    id: 0,
    name: "total",
    value: 20
  });

(这一切都有效并且在 indexedDb 中可见)我也尝试过daysMax={$total}

代码沙盒

托马斯·亨内斯

正如您所说,您的数据库设置和初始写入操作已正确完成。问题在于您的查询:

  let total = liveQuery(() =>
    db.storage
      .where("name")
      .equals("total")
      .value.then(function(a) {
        totals = a;
      })
  );

首先,查询的WhereClause部分 ( db.storage.where("name").equals("total")) 返回一个Collection,引用文档:

表示数据库对象的集合。请注意,它本身不会包含任何对象。相反,它为如何执行数据库查询做准备。调用返回 Promise 的方法时会执行查询,例如 toArray()、keys()、count() 或 each()。

因此,您不能.value像在代码中那样简单地取消引用。您必须改为使用 Collection 提供的方法之一。由于在您的用例中,您只希望在数据库中找到一个匹配项,因此我会推荐Collection.first()在这里,它返回一个最终解析为您正在查询的数据的 Promise。

因此,您的查询应如下所示:

  let total = liveQuery(() =>
    db.storage
      .where("name")
      .equals("total")
      .first()
  );

接下来是你使用的方式liveQueryliveQuery()所做的是将 Promise(您现在将从上一步收到的)转换为 Observable。如文档中所述:

Svelte Store Contract 是 Ecmascript Observable 规范草案的子集,它使 liveQuery() 的返回值本身成为完全有效的 Svelte Store。

这意味着total实际上它的行为类似于Svelte(可读)存储,可以订阅或使用简写$语法访问。这意味着$total一旦查询完成并且promise 解决,它将保留与您的查询匹配的数据库对象。

并且因为它是一个 Observable(因此是一个 Svelte 存储),所以对数据库记录所做的任何更新都会立即反映在$total.

最后要做的是访问value数据库对象的属性。因为$total最初将undefined在查询运行并且承诺解决时,所以我还要添加一个条件。为此,我建议使用一个小的响应式声明来保持整洁,选择一个允许您使用速记道具表示法的变量名称,并结合一个条件来仅在查询已解决时显示计数器:

<script>
    // ...your existing script code with updated query...
    $: daysMax = $total?.value // undefined until the query resolves, actual value once the query has resolved
</script>

<main>
    {#if daysMax !== undefined}
        <Counter daysLeft={left} {daysMax} />
    {/if}
    <New />
    <History />
</main>

分叉的、工作的 CodeSandbox

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章