07 февраля 2011

Майкл Сандберг. Начало работы с compojure, часть 2

Перевод. Оригинал
Это вторая часть моего введения в вебпрограммирование с clojure. В первой части мы сделали небольшой "список задач", который получился не очень-то функциональным. Но мы сделали это сами!

В этой части мы добавим JavaScript и Ajax!
Для этого мы должны иметь возможность хранить статические файлы. Это очень просто. Начнем с создания папки "files" в папке Вашего проекта (например, в той же папке, что и project.clj)
В созданной папке, создайте javascript.js и введите в него некоторый текст.

Теперь вернемся к core.clj.
Необходимо сообщить compojure/ring что мы храним некоторые файлы. Мы сделаем это, обернув наш вызов my-routes в функции jetty, чтобы улучшить читабельность, мы также переместим это в новую функцию.


Мы также добавим: ring.middleware.file-info и ring.middleware.file в (:use ) часть декларации пространства.

Теперь если Вы перейдете по адресу http://localhost:8080/javascript.js вы увидите содержимое Вашего файла.

Пришло время для некоторой ajax магии, для упрощения жизни, мы будем использовать jquery, и jquery плагин jquery.form.
Вы можете найти его по адресу: http://github.com/malsup/form/raw/master/jquery.form.js?v2.43
и jquery с jquery.org и поместите их в Ваш каталог "files".

Попробуйте загрузить их в броузере: http://localhost:8080/jquery.min.js это должно сработать.

Для включения их в Ваш clojure код, мы можем использовать некоторые вспомогательные функции из hiccup.


Загрузите форму в Вашей вебстранице и Вы должны увидеть: и так далее.

Теперь мы можем немного попрограммировать на JavaScript!
Откройте ваш javascript.js и введите следующее:


#formresult, это css id тега в котором будет результат POST запроса от формы.
Мы хотим, чтобы это было в div под формой. Div выглядит так:
[:div {:id "formresult"} “form result will be here”]

Итак, вся функция должна выглядеть следующим образом:


Теперь скомпилируйте функцию и протестируйте форму. Когда Вы нажмете enter, перезагрузки страницы не произойдет. "form result here" будет заменен на task3 ["task1" "task2"], если Вы ввели task1,task2 and task3 в вашей форме. Круто, да? Мы хотим, чтобы это выглядело как в /view. Проще простого!


Мы просто перенесли часть создания вектора "списка задач" в let конструкцию. Теперь вектор у нас под рукой и можем снова использовать функцию (unordered-list) для придания красоты нашему списку. Примечание: (html) также был добавлен.

Убедитесь, что все сделано правильно, вот мой код:
 core.clj

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

Мы начнем с создания нового маршрута:

(GET “/delete/:task” {session :session, params :params} (delete-task (params “task”) session))

Примечание, если мы не нуждаемся в параметре session мы можем использовать сокращенную версию:

(GET “/delete/:task” [task] (delete-task task session)

:task помещает что-либо написанное на этом месте в параметр. Если Вы перейдете по ссылке http://localhost:8080/delete/mytask это вызовет функцию delete-task с параметром mytask.

Определим функцию delete-task.
(defn delete-task [task] )
Теперь вопрос: как удалить "задачу" из вектора? Вектора поддерживают удаление только по индексу. Простейший способ сделать это сконверитровать вектор во множество. Просто измените vector? на set? и (vector на (hash-set. Все заработало!

Теперь мы можем написать нашу функцию:



Создайте несколько "задач". Затем введите http://localhost:8080/delete/sometask и sometask удалиться! Вы можете проверить это используя /view.

Но давайте быть честными, это не самый удобный способ удаления. Мы хотим иметь возможность нажать на кнопку, чтобы удалить "задачу".

Мы решим это также с помощью JQuery:


Что мы сделали? Мы создали функцию с именем done, она добавляет clickListener для всех элементов списка. clickListener вызывает /delete/list-item-text и при успехе скрывает элемент.

Достаточно для второй части.
Мой полный core.clj

Запущенную версию можно увидеть здесь:  http://cljtasks.appspot.com/
Спасибо за великолепней руководства: http://compojureongae.posterous.com/
за помощью в развертывании приложения на app engine!

В следующей части мы попробуем сохранить наш "список задач" в NoSQL базу данных.

Комментариев нет:

Отправить комментарий