英文:
Can we have index on indexedDb using dart in flutter web?
问题
我尝试在Flutter Web中实现Hive,但发现它不支持添加索引。底层的indexedDb支持添加index,但Hive不支持(至少我找不到任何示例或文档)。
我尝试使用idb_shim来实现,它有关于向数据库添加索引的官方文档。
当我尝试使用idb_shim
向indexDb添加Dart对象时,它会抛出错误UnimplementedError: structured clone of other type
,对于某些条目。以下是添加的代码:
IdbFactory idbFactory = getIdbFactory();
_db = await idbFactory.open(boxName,
version: 1, onUpgradeNeeded: this.onUpgradeNeeded);
var txn = _db.transaction(boxName, idbModeReadWrite);
var store = txn.objectStore(boxName);
await store.put(value, key);
await txn.completed;
类似地,当我尝试读取对象时,它以ArrayBuffer
的形式存在,而不是JSON对象。没有文档明确说明如何在indexedDb中存储/读取Dart对象。
var txn = _db.transaction(boxName, idbModeReadOnly);
var store = txn.objectStore(boxName);
final value = await store.getObject(key);
print(value); // ArrayBuffer
await txn.completed;
return value as T; // 转换为实际Dart对象时会抛出错误
-
我们是否需要使用
dart:js
包将Dart对象转换为JavaScript对象? -
我们是否需要将对象存储为字符串化的JSON字符串?在这种情况下,索引可能不起作用?
英文:
I have tried implementing Hive for flutter web, but found out that it doesn't provide adding indexes. The underlying indexedDb provided adding index but Hive doesn't provide (at least I couldn't find any example or docs)
I am trying to implement idb_shim, which has official docs for adding index to database.
When I am trying to add a dart object
to indexDb using idb_shim
it throws an error UnimplementedError: structured clone of other type
for some entries. Following is code to add
IdbFactory idbFactory = getIdbFactory();
_db = await idbFactory.open(boxName,
version: 1, onUpgradeNeeded: this.onUpgradeNeeded);
var txn = _db.transaction(boxName, idbModeReadWrite);
var store = txn.objectStore(boxName);
await store.put(value, key);
await txn.completed;
Similarly, when I am trying to read the object, it is in form of ArrayBuffer
not the JSON object. There is no docs indicating clearly on how to store/read dart objects
in indexedDb.
var txn = _db.transaction(boxName, idbModeReadOnly);
var store = txn.objectStore(boxName);
final value = await store.getObject(key);
print(value); // ArrayBuffer
await txn.completed;
return value as T; // throws error when converting to actual dart-object
-
Do we need to convert dart-objects to Javascript Objects using
dart:js
package? -
Do we need to store the object in stringified JSON string? In this case index may not work?
答案1
得分: 0
我已找到解决方案:
我们是否需要使用dart:js包将Dart对象转换为JavaScript对象?
是的,我们需要创建不同的对象,使用以下语法:
import 'package:js/js.dart';
@JS()
@anonymous
abstract class JsItem {
external bool get prop1;
external int get prop2;
external String get prop3;
external String get bulk_data;
external factory JsItem({int prop2 = 0, String prop3 = '', String bulk_data = '', bool prop1 = false});
}
在插入到IndexedDB
时,您可以插入对象JsItem()
。
我们是否需要将对象存储为字符串化的JSON字符串?在这种情况下,索引可能无法工作?
我已经克服了这个问题,通过将大多数数据(除了索引属性)转换为JSON
字符串并插入到bulk_data
中。在这里,prop1
、prop2
和prop3
是索引属性。
读取数据
从indexedDB
中读取数据时,它以LinkedList
映射的格式呈现,所有属性都可以作为map
属性读取。因此,创建一个类似下面的辅助函数会很有帮助:
toDartItem(LinkedMap map){
return DartItem({ prop1: map["prop1"],
prop2: map["prop2"],
prop3: map["prop3"],
bulk_data: map["bulk_data"], // 根据需要将JSON转换为不同的属性
)};
}
英文:
I have found solution to both issues:
Do we need to convert dart-objects to Javascript Objects using dart:js package?
Yes, we need to create different objects with following syntax:
import 'package:js/js.dart';
@JS()
@anonymous
abstract class JsItem {
external bool get prop1;
external int get prop2;
external String get prop3;
external String get bulk_data;
external factory JsItem({int prop2 = 0, String prop3 = '', String bulk_data = '', bool prop1 = false});
}
While inserting to IndexedDB
you can insert the object JsItem()
.
Do we need to store the object in stringified JSON string? In this case index may not work?
I have overcome of this issue by converting most of data (excluding indexes properties) to JSON
string and inserting into bulk_data
. Here prop1
, prop2
, prop3
are indexes.
Reading the data
While reading the data form indexedDB
it comes in format of LinkedList
map and all properties can be read as map
properties. So it would be helpful to create a helper function like below:
toDartItem(LinkedMap map){
return DartItem({ prop1: map["prop1"],
prop2: map["prop2"],
prop3: map["prop3"],
bulk_data: map["bulk_data"], // Convert JSOn to different props as required
)};
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论