Устаревайте данные с помощью StimulusJS и редактора Quill

Я интегрирую редактор Quill с Rails и хотел бы управлять им с помощью StimulusJS. По сути, у меня есть поле в форме Rails, в котором хранится html, и он становится редактором форматированного текста Quill. Есть также 2 других поля, потребляющих данные из Quill: простой текст (без тегов) и дельты (журнал изменений).

Все три затем сохраняются в БД через обычную форму отправки.

Это почти работает.

Форма и код контроллера

<div data-controller='quill'>
      <%= f.input :target_note,
            input_html: {
              data: {
                target: 'quill.editor',
                action: "keyup->quill#update" } } %>
      <input data-target='quill.delta'/>
      <input data-target='quill.text' />
    </div>

Стимул контроллер

import { Controller } from "stimulus";

export default class extends Controller {
  static targets = ['editor','delta','text'];

  connect() {
    console.log('connected');
    this.quill = new Quill('#grammar_note_target_note', {
      theme: 'snow'
    });
  }

  update(){
    console.log(this.quill.getContents());
    console.log(this.quill.getText());
    this.textTarget.value = this.quill.getText();
    this.deltaTarget.value = this.quill.getContents();
  }
}

проблема

Когда пользователь вводит данные в поле редактора, ранее сохраненные данные копируются в виде дельта / простого текста в поля textTarget и deltaTarget. На изображении ниже значение "asdasdasdsa" ранее было сохранено в поле, в то время как пользователь просто набрал "hhh".

Ожидаемое поведение

При каждом нажатии клавиши фактический текст будет преобразован в дельты или текст и сохранен в 2 полях.

Любая помощь будет принята с благодарностью.: Ухмылка:

редактировать

@jhchen каждое нажатие клавиши производит те же, оригинальные данные, которые были в поле. Изменения отображаются на экране, но не на 2 входах или консоли.

1 ответ

Ну, у меня все работает, но я не продаюсь на 100% на StimulusJS. Возможно, есть лучший способ сделать это, но это мое решение:

Javascript

import { Controller } from "stimulus";

export default class extends Controller {
  static targets = ['editor','html','text'];

  initialize() {
    this.quill = new Quill(this.editorTarget, {
      theme: 'snow'
    });
    this.quill.on("text-change", e => {
      this.textChange();
    });
 }

 textChange(){
    this.htmlTarget.value = this.quill.root.innerHTML;
    this.textTarget.value = this.quill.getText();
 }

}

Посмотреть

<div data-controller='quill'>
    <div data-target='quill.editor'>
      <% if f.object.target_note.present? %>
        <%= f.object.target_note.html_safe %>
      <% end %>
    </div>
    <%= f.input :target_note,
          label: false,
          input_html: {
            class: 'display-none',
            data: { target: 'quill.html' } } %>
    <%= f.input :target_note_text,
          label: false,
          input_html: {
            class: 'display-none',
            data: { target: 'quill.text' }
          } %>
  </div>

display-none класс и label: false где необходимо, поскольку StimulusJS не может нацелиться на скрытое поле!!!

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