Использование базы данных Flutter Isar в модели
В настоящее время я создаю базу данных с помощью Isar, которая выглядит следующим образом:
@collection
class Polygon {
Id id = Isar.autoIncrement;
final vertices = IsarLinks<Vertex>();
late Color color;
}
@collection
class Vertex {
Id id = Isar.autoIncrement;
final polygon = IsarLink<Polygon>();
late Offset point;
}
В моем коде у меня есть изображение, на котором я рисую эти многоугольники, используя событие GestureDetector onTapUp:
List<Vertex>? _currentVertices;
void addVertex(details) async {
Offset pos = details.localPosition;
if (_currentVertices == null) {
_currentVertices = [Vertex()..point = pos];
} else {
if (_currentVertices!.length > 2 &&
(_currentVertices!.first.point - pos).distance <= 20 ) {
// Create a new polygon from the list of vertices and save it to the database
Polygon p = Polygon();
// Set the polygon for each vertex
for (var v in _currentVertices!) {
v.polygon.value = p;
}
// Save it into the database
await _isar.writeTxn(() async {
await _isar.polygons.put(p);
});
_currentVertices = null;
} else {
// Add point to current list of vertices
_currentVertices!.add(Vertex()..point = pos);
}
}
}
Но когда я это сделаю, многоугольник появится в базе данных, а вершины — нет. Итак, я попробовал:
await _isar.writeTxn(() async {
await _isar.polygons.put(p);
});
for (var v in _currentVertices!) {
await _isar.writeTxn(() async {
await _isar.vertexs.put(v);
});
}
Теперь и полигоны, и вершины находятся в базе данных, но идентификаторы/IsarLinks не установлены...
- Есть ли у кого-нибудь пример того, как вам следует это сделать?
Во-вторых:
На самом деле я читал об использовании провайдера здесь (внутри класса PolygonModel). Итак, как только у меня появится класс PolygonModel (чтобы мое представление могло отслеживать изменения в полигонах), мне понадобится метод PolygonModel.addPolygon(p).
Должен ли я реализовать как модель Polygon, так и модель Vertex? На самом деле мне не нужна модель Vertex в качестве уведомления об изменениях, так что это кажется излишним. Так что я должен просто сделать:
// Create a new polygon from the list of vertices and save to the database
Polygon p = Polygon();
for (var v in _currentVertices!) {
v.polygon.value = p;
}
// Add both the polygon and vertices to the database
polygonModel.addPolygon(p, _currentVertices!);
Или мне действительно нужно сделать что-то вроде:
// Create a new polygon from the list of vertices and save to the database
Polygon p = Polygon();
polygonModel.addPolygon(p);
for(var v in _currentVertices!) {
vertexModel.addVertex(p, v);
}
Опять же, были бы полезны любые ссылки на подходящие примеры подобной реализации (сейчас я собирался использовать провайдер/провайдер.dart, но также читал о Riverpod, который может быть лучшим решением).
1 ответ
Хорошо, я думаю, что решил эту проблему, реальная проблема в том, что я перешел с синхронных транзакций на асинхронные...
Isar автоматически сохраняет все IsarLinks в компоненте, когда вы используете синхронную транзакцию, а не асинхронную... Таким образом, частью решения является правильное сохранение элементов IsarLink компонента при сохранении компонента. Итак, если бы, например, у меня был родительский компонент многоугольного компонента, имеющий связь один к одному, вы бы сделали:
// Save it into the database
await _isar.writeTxn(() async {
await _isar.parents.put(parent);
await parent.polygon.save();
});
Это сохранит новый родительский объект в базе данных isar, а затем сохранит IsarLink в полигоне (где на каждого родителя приходится один полигон).
Чтобы решить проблему с IsarLinks to Vertex, я пошел простым путем и вместо этого использовал встроенный:
@collection
class Parent {
Id id = Isar.autoIncrement;
final polygon = IsarLink<Polygon>();
}
@collection
class Polygon {
Id id = Isar.autoIncrement;
List<Vertex>? vertices;
}
@embedded
class Vertex {
late double x;
late double y;
}
На самом деле это не обман, потому что это правильный способ сделать такую вещь (вершины не являются общими для разных полигонов). Но это также означает, что я обхожу сохранение IsarLinks. Но я вернусь к этому как-нибудь позже... Комментарии будут полезны.
Второй выпуск:
Опять же, я использовал самое простое решение. Поскольку вершины на самом деле теперь представляют собой просто список «встроенных», они автоматически сохраняются вместе с многоугольником. Я не уверен, что действительно ответил на свои вопросы, но надеюсь, что кто-то еще сможет поучиться здесь из моих мыслей.