Как отменить изменения в несинхронизированной коллекции?

Как я могу отменить несинхронизированные изменения в базе данных?

Сценарий использования

Я хочу дать пользователю возможность отменить операцию над базой данных (т.е. удалить) в течение как минимум нескольких секунд после того, как он это сделает.

Можно было бы задержать удаление из базы данных до тех пор, пока не пройдет время, чтобы отменить ее, однако я думаю, что было бы более упорядоченным отразить в коде то, что я увижу в пользовательском интерфейсе, просто чтобы сохранить вещи 1:1,

Итак, я попытался сохранить объект перед удалением, а затем обновить его (чтобы его _status больше не будет удален)

 this.lastDeletedDoc = this.docs[this.lastDeletedDocIndex];

 // remove from the db
 this.documents.delete(docId)
  .then(console.log.bind(console))
  .catch(console.error.bind(console));

// ...

// user taps "UNDO"
this.documents.update(this.lastDeletedDoc)
  .then(console.log.bind(console))
  .catch(console.error.bind(console));

но я получил ошибку Error: Record with id=65660f62-3eb1-47b7-8746-5d0b2ef44eeb not found,

Я также попытался создать объект снова с помощью:

// user taps "UNDO"
this.documents.create(this.lastDeletedDoc, { useRecordId: true })
   .then(console.log.bind(console))
   .catch(console.error.bind(console));

но я получаю Id already present ошибка.

Я также быстро просмотрел исходный код, но не смог найти undo функции.

Как я обычно отменяю изменения в несинхронизированной коллекции кинто?

2 ответа

Решение

Таким образом, вы сможете найти запись назад и установить ее _status к своей старой предыдущей версии, как вы делаете.

Проблема заключается в том, что get метод принимает includeDeleted опция, которая позволяет вам извлечь удаленные записи, но update Метод не передает эту опцию.

Лучший способ исправить это, вероятно, открыть запрос на извлечение в репозитории Kinto.js, сделав update метод принять includeDeleted вариант, что он перейдет к get метод.

Из-за ограниченного соединения сейчас я не могу выдвинуть изменения, но это выглядело бы в основном так (+ тест, который демонстрирует, что это работает должным образом):

diff --git a/src/collection.js b/src/collection.js
index c0cce02..a0bf0e4 100644
--- a/src/collection.js
+++ b/src/collection.js
@@ -469,7 +469,7 @@ export default class Collection {
    * @param  {Object} options
    * @return {Promise}
    */
-  update(record, options={synced: false, patch: false}) {
+  update(record, options={synced: false, patch: false, includeDeleted:false}) {
     if (typeof(record) !== "object") {
       return Promise.reject(new Error("Record is not an object."));
     }
@@ -479,7 +479,7 @@ export default class Collection {
     if (!this.idSchema.validate(record.id)) {
       return Promise.reject(new Error(`Invalid Id: ${record.id}`));
     }
-    return this.get(record.id)
+    return this.get(record.id, {includeDeleted: options.includeDeleted})
       .then((res) => {
         const existing = res.data;
         const newStatus = options.synced ? "synced" : "updated";

Не стесняйтесь подавать запрос на удаление с этими изменениями, я считаю, что это должно решить вашу проблему!

Я не уверен, является ли сочетание "несинхронизированный" с "пользователь может отменить" хорошим принципом проектирования. Если вы уверены, что вы когда-нибудь захотите отменить удаление, то это поможет сработать таким образом в функциональности задержки отмены, но что если в будущем вы захотите поддерживать отмену обновлений? Старое значение уже будет потеряно.

Я думаю, что вы должны сделать в своем приложении добавить коллекцию, называемую "история отмен", где вы храните объекты со всеми данными, необходимыми для отмены пользовательских операций. Если вы синхронизируете эту коллекцию, то вы даже сможете удалить что-то на своем телефоне, а затем отменить это на своем ноутбуке!:)

Другие вопросы по тегам