Как создать веб-приложение Woooo-like (form builder) с помощью JQuery и Rails?

Я ищу некоторые рекомендации о том, как реализовать Wufoo-like builder в приложении Rails 3 с JQuery на стороне клиента, В принципе, пользователь может что-то создать (форма в случае Wufoo) в режиме "офлайн", а затем сохранить все изменения пользователя на сервере в одной партии, нажав кнопку "Сохранить" или аналогичную (например, может быть автоматическое сохранение, вызванное браузер каждые 30 секунд или около того).

Я склоняюсь к использованию локального хранилища HTML5 в этот момент. "Строитель", по существу, будет хранить пользовательские изменения локально в локальном хранилище браузера в формате JSON. Щелчок по кнопке "Сохранить" будет затем HTTP. Поместите содержимое локального хранилища в приложение Rails снова в формате JSON. Звучит ли это правильно? Любые советы, предложения?

Некоторые дополнительные соображения/вопросы:

  • Что относительно старых браузеров, которые не поддерживают HTML5? Должен ли быть резервный план, в котором используется хранилище файлов cookie?
  • Любой плагин JQuery, который может помочь с некоторыми из этого? например абстрактное локальное хранилище HTML5 в качестве основного хранилища и хранилища файлов cookie в качестве вторичного/резервного хранилища.
  • Любые специфические для Rails соображения, о которых нужно знать?

Примечание. Следующий вопрос касается конструктора форм WYSIWYG специально и на самом деле не дает никакого хорошего решения. Создание конструктора форм WYSIWYG (a la Wufoo) в Rails

Спасибо!

Ответы

Ответ 1

Я играл с этим немного на работе, и я думаю, что это может дать вам начало в построителе форм jquery, который знает, как сериализовать и десериализовать себя. Я думаю, что он сериализует форму в строку, а не в JSON, но это начало. http://www.botsko.net/blog/2009/04/07/jquery-form-builder-plugin/

В google search нашли меня sites.google.com/site/daveschindler/jquery-html5-storage-plugin, в котором говорится, что он хранит вещи в хранилище HTML 5 с резервным копированием файлов cookie, если браузер не поддерживает его.

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

Надеюсь, что это поможет.

Ответ 2

В этом дизайне я закончил реализацию. Я далек от полного решения, но думаю, что это хороший старт.

Модель данных

В моем случае пользователи должны иметь возможность создавать список задач, в которых задачи могут иметь разные типы и, следовательно, атрибуты. Задачи также могут встраивать дополнительные объекты. Подобно построителю формы в некотором смысле, хотя я имею дело с более глубокой иерархией вложенных объектов. Ключевым моментом здесь является обеспечение того, чтобы ваше фоновое приложение предоставляло только объекты, относящиеся к домену вашего приложения (в смысле Domain Driven Design), чтобы ваш клиентский код не тратил время на рефакторинг данных после десериализации его с помощью вызова сервера и перед его сериализацией при подготовке к Save. В связи с этим мне пришлось внести несколько изменений в мой уровень представления на стороне сервера, но в результате я считаю, что мой клиентский код более чист и более сфокусирован на обработке фактических пользовательских событий.

Сериализация данных

Я выбрал JSON в качестве формата обмена данными. На стороне клиента у меня есть две функции, которые обрабатывают сериализацию данных и десериализацию. Реализация довольно прямолинейна (частично благодаря некоторым изменениям, которые я сделал, чтобы выявить объекты модели домена). Я вставил упрощенную версию ниже. Единственная проблема заключалась в том, что параметр _method, используемый Rails для обработки запросов PUT, похоже, не работает с JSON Content-Type. См. Использование HTTP PUT для отправки JSON с помощью JQuery и Rails 3

var todoList = {};

$.getJSON("/users/123/todolists/456.json", function(data) {
  loadTodoList(data);
  ...
});

function loadTodoList(data) {
  todoList = data.todoList;
}

function saveTodoList() {
  $.ajax({
    type: 'POST',
    url: "/users/123/todolists/456",
    data: JSON.stringify({ todoList: todoList }),
    contentType: 'application/json',
    dataType: 'script', // could be "json", "html" too
    beforeSend: function(xhr){
      xhr.setRequestHeader("X-Http-Method-Override", "put");
    }
  });
}

На стороне сервера Rails упрощает обработку JSON (сериализация и десериализация JSON выполняется автоматически и прозрачно с помощью фреймворка). Я просто переопределил метод to_json() на моей модели TodoList, чтобы избежать передачи ненужных данных (например, create_at, modified_at). Также необходимо было включить все вложенные объекты при извлечении моего объекта верхнего уровня (т.е. TodoList).

  # TodoListsController
  def show
    @todolist = TodoList.find_by_id(params[:id], :include => [:tasks, ...])
    respond_to do |format|
      format.json do
        render :json => @todolist.to_json
      end
    end
  end

  # TodoList model
  def to_json
    super(:only => :name,
          :include => { :tasks => { :only => [:name, :description, ...],
                                    :include => ... }})
  end

Настойчивость на стороне клиента

Цель состоит в том, чтобы избежать случайной потери прав пользователя, которые не были сохранены. Пока я напрямую использую локальное хранилище HTML5 (переменная localStorage), но в конечном итоге будет искать плагин jQuery, который автоматически обрабатывает отказ от хранения файлов cookie, если HTML5 не поддерживается.

Динамическое генерирование HTML

Я полагаюсь на jQuery Template для генерации HTML. Основная функция строителя - динамически генерировать HTML, поэтому этот плагин очень удобен. Я определил шаблоны для всех строительных блоков моей модели списка дел (например, задач, заметок,...). Шаблоны вызывается каждый раз, когда создаются новые экземпляры этих объектов и их нужно визуализировать.

Я думаю, что это основная часть фундамента. Остальное - это, в основном, хардкорный Javascript для обработки всех пользовательских взаимодействий с помощью компоновщика form/todoList.