Как создать веб-приложение 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.