Как отменить изменения в несинхронизированной коллекции?
Как я могу отменить несинхронизированные изменения в базе данных?
Сценарий использования
Я хочу дать пользователю возможность отменить операцию над базой данных (т.е. удалить) в течение как минимум нескольких секунд после того, как он это сделает.
Можно было бы задержать удаление из базы данных до тех пор, пока не пройдет время, чтобы отменить ее, однако я думаю, что было бы более упорядоченным отразить в коде то, что я увижу в пользовательском интерфейсе, просто чтобы сохранить вещи 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";
Не стесняйтесь подавать запрос на удаление с этими изменениями, я считаю, что это должно решить вашу проблему!
Я не уверен, является ли сочетание "несинхронизированный" с "пользователь может отменить" хорошим принципом проектирования. Если вы уверены, что вы когда-нибудь захотите отменить удаление, то это поможет сработать таким образом в функциональности задержки отмены, но что если в будущем вы захотите поддерживать отмену обновлений? Старое значение уже будет потеряно.
Я думаю, что вы должны сделать в своем приложении добавить коллекцию, называемую "история отмен", где вы храните объекты со всеми данными, необходимыми для отмены пользовательских операций. Если вы синхронизируете эту коллекцию, то вы даже сможете удалить что-то на своем телефоне, а затем отменить это на своем ноутбуке!:)