Функция отмены последнего действия (Undo) - это просто (Часть 1.5)
27 September 2007Продолжаю переводить серию статей о реализации Undo.
Это вторая часть первой части серии заметок “Функция отмены последнего действия (Undo)”. Если вы её пропустили, то сначала прочитайте первую часть (перевод первой части).Один с моих читателей, Alex Botero-Lowry, отметил большую проблему реализации Undo c очереди полностью на стороне клиента: если пользователь открывает эту же страницу на второй вкладке браузера для просмотра, то эти страницы могут быть не синхронизированы. В примере to-do листа, если вы удаляете три to-do листа и открываете новую вкладку или окно этой же страницы, то эти to-do всё-таки останутся. Почему? Потому что первая страница знает о удалении (хотя оно и не законченное), а вторая - нет.
Возьмем клиентский подход и запустим его. В том, что нет запутанного back-end’а есть что-то красивое. Мы можем исправить проблему множественных вкладок, синхронизируя очередь событий со всех открытых страниц с помощью кукиз (cookie).
Хочу подчеркнуть, что метод очереди событий - очень легкое решение отмены действия. Существуют другие, более надёжные пути реализации Undo, такие как основаные на серверной стороне command pattern (пару моих читателей обратили на это внимание и я, возможно, рассмотрю это в следующих заметках). Но это не относится к делу. Когда мы, как инженеры, стараемся решить сложные проблемы, мы часто слишком обобщаем и слишком абстрагируемся к своему back-end решению, не замечая других вариантов. Когда мы делаем это, мы пропускаем простые решения, которые могут помочь пользователям уже сейчас. Некоторые формы Undo как низко-висячие фрукты, почему же не сорвать их? Конец отступления.
Повторяю, мы решаем что случится, когда пользователь удалит некоторые элементы, откроет другую вкладку этой же страницы и те пункты, оказывается, не удалены. Предположим, что очередь событий хранит идентификаторы удалённых объектов и каждый раз когда элемент удаляется или удаление незаконченное, мы пишем очередь в cookie; когда страница закрывается - мы очищаем куки. Когда страница загружается - мы проверяем куки и если в них есть не пустой список, то мы на стороне клиента “удаляем” элементы и добавляем их в очередь. Теперь каждая новая вкладка/окно открывается, мы гарантировано синхронизируем их.
Проблема решена.
Сложность
Итак, что случится когда вы сделаете изменения на одной странице, а потом переключитесь на другую, уже открытую страницу? Это может усложнить жизнь. Мы спасены от необходимости иметь дело с всей проблемой, потому что web не технология “толчка”. В настоящее время, никакое приложение сети, о котором я знаю, без возможности ручного обновления, не может обновить страницу, когда она изменена в другой вкладке. Пользователи используют обновление страницы, чтобы увидеть изменения. Это означает, что мы должны правильно обходится с вариантом, когда пользователь удаляет и восстанавливает данные в одной вкладке, возвращается в другую и нажимает refresh.
Чтобы решить эту проблему, мы должны сделать предположение, что последняя вкладка/окно, в котором пользователь что-то редактировал, содержит наиболее актуальную информацию. Это резонное предположение, потому что последнее с чем пользователь работал, наиболее вероятно будет тем, о чем пользователь думал как последняя версия.
Когда же пользователь обновляет страницу, вызывается метод onUnload. В нём мы должны проверить, совпадает ли очередь страницы с очередью последней сохранённой в кукисах очередью (помните, что очередь событий сохраняется в cookie, когда пользователь удаляет или отменяет удаление). Если две очереди одинаковые, то страница актуальна и мы продолжаем передачу изменений ксерверу. Если две очереди не одинаковые, то текущая страница требует синхронизации с сохранённой в куках очередью, в результате чего она обновляется.
Попробуйте
Поиграйте с этим, затем откройте новое окно браузера. Теперь, измените что-то в новом окне и потом обновите старое окно. Всё правильно обновляется.
Исходный код
Заключение
Польза от пути cookie заключается в том, что это улучшает положение с уже редком случае, когда пользователь теряет свою работу в случае краша браузера. Когда браузер “падает”, то все изменения сохраняются в куках, итак, когда пользователь загружает страницу опять, его изменения вся-таки применяться.
Система очереди событий с синхронизацией на куках - это низковисячий фрукт. Это работает не везде, но будет работать в поразительно большом количестве случаев. Это стоит сравнительно небольших сроков.
На следующей неделе, я напишу о решении Undo для время-зависимых действий.
Перевод: Undo Made Easy with Ajax (Part 1.5)



2 Responses to “Функция отмены последнего действия (Undo) - это просто (Часть 1.5)”
September 28th, 2007 at 2:13 pm
Респект… Статья класс!
August 14th, 2008 at 5:32 pm
qwewe