Как я могу хранить составленные изменения, используя Quill? - PullRequest
0 голосов
/ 01 апреля 2019

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

Для этого я наблюдаю за событием 'text-change', и каждая операция сохраняется в базе данных моего приложения. Время от времени (каждую минуту) я сочиняю изменения, внесенные в документ, с предыдущим состоянием документа и выполняю различие между результатом этой композиции и предыдущим состоянием документа, сохраняя результат сравнения и удаляя предыдущие операции. потому что они в разном результате.

Чтобы получить предыдущее состояние документа, сначала я использую исходную дельту документа. Затем при сохранении различий я просто составляю исходную дельту документа с разностями, существующими в базе данных. Например:

Оригинал документа дельта: {"ops":[{"insert":"Evaluation Only. Created with Aspose.Words. Copyright 2003-2018 Aspose Pty Ltd.","attributes":{"size":"16px","font":"Calibri","bold":true,"color":"#FF0000"}},{"insert":"\n","attributes":{"paragraph":true,"spacing_before":"0px","spacing_after":"10.67px","indent":0,"text_indent":"0px","line_spacing":"17.27px"}},{"insert":"Test","attributes":{"size":"14.67px","font":"Calibri","color":"#000000"}},{"insert":"s","attributes":{"size":"14.67px","font":"Calibri","color":"#000000"}},{"insert":"\n","attributes":{"paragraph":true,"spacing_before":"0px","spacing_after":"10.67px","indent":0,"text_indent":"0px","line_spacing":"17.27px"}}],"page_setup":{"left_margin":"113.4px","top_margin":"94.47px","right_margin":"113.4px","bottom_margin":"94.47px"}}

Первое изменение: {"ops":[{"delete":80}]}

Второе изменение: {"ops":[{"retain":5},{"insert":"\n","attributes":{"spacing_before":"0px","spacing_after":"10.67px","text_indent":"0px","line_spacing":"17.27px"}}]}

Третье изменение: {"ops":[{"retain":6},{"insert":"A","attributes":{"color":"#000000"}}]}

Код, который я использую, показан ниже:

var diffs = result.diffs;
var deltas = result.deltas;

var lastComposedDelta = null;

for (var i = 0; i < diffs.length; i++) {
    var currentDelta = newDelta(diffs[i].Value);

    if (lastComposedDelta == null) {
        lastComposedDelta = currentDelta;
    } else {
        lastComposedDelta = lastComposedDelta.compose(currentDelta);
    }
}

var composedDeltas = lastComposedDelta;

for (var i = 0; i < deltas.length; i++) {
    var currentDelta = newDelta(deltas[i].Value);

    if (composedDeltas == null) {
        composedDeltas = currentDelta;
    } else {
        composedDeltas = composedDeltas.compose(currentDelta);
    }
}

var diffDelta = composedDeltas;
if (lastComposedDelta != null) {
    diffDelta = lastComposedDelta.diff(composedDeltas);
}

Результат этого различия: {"ops":[{"delete":80},{"retain":5},{"retain":1,"attributes":{"paragraph":null,"indent":null}},{"attributes":{"color":"#000000"},"insert":"A"},{"attributes":{"paragraph":true,"spacing_before":"0px","spacing_after":"10.67px","indent":0,"text_indent":"0px","line_spacing":"17.27px"},"insert":"\n"}]}

Проблема, с которой я столкнулся, это когда пользователь вставляет новую строку и делает отступ, например. Дельта таких операций:

Новая строка: {"ops":[{"retain":8},{"insert":"\n"}]}

Отступ: {"ops":[{"retain":9},{"retain":1,"attributes":{"indent":1}}]}

Затем, когда я пытаюсь изменить документ, используя приведенный выше код, выдает ошибку:

Uncaught Error: diff() called with non-document

Значение "lastComposedDelta": {"ops":[{"insert":"Tests","attributes":{"size":"14.67px","font":"Calibri","color":"#000000"}},{"insert":"\n","attributes":{"spacing_before":"0px","spacing_after":"10.67px","text_indent":"0px","line_spacing":"17.27px"}},{"attributes":{"color":"#000000"},"insert":"A"},{"attributes":{"paragraph":true,"spacing_before":"0px","spacing_after":"10.67px","indent":0,"text_indent":"0px","line_spacing":"17.27px"},"insert":"\n"},{"delete":80},{"retain":5},{"retain":1,"attributes":{"paragraph":null,"indent":null}},{"insert":"A","attributes":{"color":"#000000"}},{"insert":"\n","attributes":{"paragraph":true,"spacing_before":"0px","spacing_after":"10.67px","indent":0,"text_indent":"0px","line_spacing":"17.27px"}}]}

Значение «compedDeltas»: {"ops":[{"insert":"Tests","attributes":{"size":"14.67px","font":"Calibri","color":"#000000"}},{"insert":"\n","attributes":{"spacing_before":"0px","spacing_after":"10.67px","text_indent":"0px","line_spacing":"17.27px"}},{"insert":"A","attributes":{"color":"#000000"}},{"insert":"\n","attributes":{"paragraph":true,"spacing_before":"0px","spacing_after":"10.67px","indent":0,"text_indent":"0px","line_spacing":"17.27px"}},{"insert":"\n"},{"delete":80},{"retain":1,"attributes":{"indent":1}},{"retain":4},{"retain":1,"attributes":{"paragraph":null,"indent":null}},{"insert":"A","attributes":{"color":"#000000"}},{"insert":"\n","attributes":{"paragraph":true,"spacing_before":"0px","spacing_after":"10.67px","indent":0,"text_indent":"0px","line_spacing":"17.27px"}}]}

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

Ответы [ 2 ]

1 голос
/ 01 апреля 2019

Если вам не нужна каждая отдельная операция, вы можете просто обновить документ по событию text-change следующим образом:

quill.on('text-change', () => {
   // By the time we hit the 'text-change' event, 
   // quill.getContents() will return the updated
   // content of the document
   const currentOps = quill.getContents();
   updateDatabase(currentOps);
});

function updateDatabase(currentOps) {
  // Do whatever you need to do with the current ops 
  // to store them. No need at all to store the diffs.
}
0 голосов
/ 08 апреля 2019

Итак, я обнаружил проблему с функцией diff. Это было потому, что когда я инициализировал редактор, я использовал функцию updateContents, чтобы установить дельту, которая была в базе данных, для редактора. Quill всегда инициализирует редактор пустой строкой. Вызывая updateContents, он составлял пустую строку с текстом из моей базы данных. Затем, когда пользователь изменял текст, дельта из редактора отличалась от дельты в базе данных.

Чтобы это исправить, я изменил функцию загрузки контента из базы данных на setContents. Таким образом, дельты из редактора и базы данных совпали.

...