Как я могу сохранить составленные изменения с помощью Quill?

#javascript #quill

#javascript #перо

Вопрос:

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

Чтобы добиться этого, я отслеживаю событие «изменение текста», и каждая операция сохраняется в базе данных моего приложения. Время от времени (каждую минуту) я объединяю изменения, внесенные в документ, с предыдущим состоянием документа и выполняю различие между результатом этой композиции и предыдущим состоянием документа, сохраняя результат различия и удаляя предыдущие операции, потому что они находятся в результате различия.

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

Дельта исходного документа: {"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"}}]}

Значение «composedDeltas»: {"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, выполняется операция «сохранить», и она не обрабатывается. Итак, я хочу знать, есть ли решение для этого, потому что я не уверен, что созданный мной код является правильным способом сделать это (сохранение различий в документе).

Ответ №1:

Если вам не нужна каждая отдельная операция, вы можете просто обновить документ по 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.
}
  

Ответ №2:

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

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