Вот дизайн, который я в итоге реализовал.Я далек от полного решения, но думаю, что это хорошее начало.
Модель данных
В моем случае пользователи должны иметь возможность составить списокзадачи, где задачи могут иметь разные типы и, следовательно, атрибуты.Задачи также могут вставлять дополнительные объекты.В некотором смысле похож на построитель форм, хотя я имею дело с более глубокой иерархией вложенных объектов.Ключевым моментом здесь является обеспечение того, чтобы ваше фоновое приложение предоставляло только объекты, относящиеся к домену вашего приложения (в смысле Domain Driven Design ), чтобы ваш клиентский код не занимал время на рефакторинг.данные после десериализации их с сервера и до их сериализации при подготовке к сохранению.В связи с этим мне пришлось внести несколько изменений в свой уровень представления на стороне сервера, но в результате я думаю, что мой код на стороне клиента стал чище и больше ориентирован на обработку реальных пользовательских событий.
Сериализация данных
Я выбрал 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 ,ified_atified).Также нужно было обязательно включить все вложенные объекты при извлечении моего объекта верхнего уровня (т.е. 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 для обработки всех взаимодействий пользователей с конструктором форм / todoList.