SammyJS пример на CoffeeScript

102 views
Skip to first unread message

ilya

unread,
Aug 29, 2012, 4:25:30 AM8/29/12
to CoffeeScript2ru (+PhoneGap)
Приветствую!

Понемногу изучаю SammyJs - некоторый аналог Синатры на Js.

Есть хороший туториал -
http://sammyjs.org/docs/tutorials/json_store_1
http://sammyjs.org/docs/tutorials/json_store_2

Я перевёл код на CoffeeScript, шаблоны на haml, бэкэндом сделал
Синатру - которая выдаёт json, и разместил демо на CloudFoundry.

Исходный код:
https://github.com/nemilya/sammyjs-coffee-json-store

Демо:
http://sammyjs-coffee-json-store.cloudfoundry.com

Текущая версия SammyJs.

Использовался для html->haml
http://html2haml.heroku.com
(при этом атрибуты переводились из :name=>"value", в name: "value")

И замечательный http://js2coffee.org

Единственное добавил в блоке @around - return, иначе не корректно
работало (в CoffeeScript возвращается выражение, по умолчанию).

На бэкэнде и на фронтэнде - используется haml.

Для запуска локально - необходимы sinatra, haml, json.
и далее ruby app.rb
по умолчанию будет взять 4567 порт (это будет выведено в консоли), и
соответственно браузером открываем http://localhost:4567

Демо содержит получение ajax запросом json данных (которые хранятся в
items.json файле) - отображение таблицы, и переход на карточку, на
карточке - форма добавления в корзину, вверху справа отображение кол-
ва товаров в корзине. Так же используется модуль сессии для хранения
данных.

В связи с некоторыми проблемами кэширования - выдача haml и json -
была сделана через Синатру:

get '/:name.haml' do
file_path = "public/templates/#{params[:name]}.haml"
File.open(file_path).read if File.exists?(file_path)
end

get "/items.json" do
JSON.parse(File.read(DATA_SOURCE)).to_json
end

где DATA_SOURCE - это путь к файлу с json данными, ясно - что выдавать
можно из любого другого источника, я просто специально пропарсил -
чтобы это уже синатра выдавала сама json.

В views/layout.haml - идёт загрузка всех необходимых библиотек.

Для Sammy загружается haml.js библиотека, и оптом модуль Sammy.haml.
Так же загружается CoffeeScript интерпретатор - и после этого JS
приложение на базе SammyJS:

%script{ :src => "app/json_store.coffee", :type => "text/
coffeescript", :charset => "utf-8" }

А вот и всё содержимое приложения:

(($) ->
app = $.sammy("#main", ->
@use "Haml"
@use "Session"
@around (callback) ->
context = this
@load("/items.json").then((items) ->
context.items = items
).then callback
# important for CoffeeScript:
return

@get "#/", (context) ->
context.app.swap ""
$.each @items, (i, item) ->
context.render("/item.haml",
id: i
item: item
).appendTo context.$element()

@get "#/item/:id", (context) ->
@item = @items[@params["id"]]
return @notFound() unless @item
@partial "/item_detail.haml"

@post "#/cart", (context) ->
item_id = @params["item_id"]

# fetch the current cart
cart = @session("cart", ->
{}
)

# this item is not yet in our cart
# initialize its quantity with 0
cart[item_id] = 0 unless cart[item_id]
cart[item_id] += parseInt(@params["quantity"], 10)

# store the cart
@session "cart", cart
@trigger "update-cart"

@bind "update-cart", ->
sum = 0
$.each @session("cart") or {}, (id, quantity) ->
sum += quantity

$(".cart-info").find(".cart-
items").text(sum).end().animate(paddingTop: "30px").animate
paddingTop: "10px"

@bind "run", ->
# initialize the cart display
@trigger "update-cart"
)
$ ->
app.run "#/"

) jQuery

Из интересного можно отметить @around - это функция которая будет
выполнена перед любым запросом (роутером), а роутер выполняется дальше
- как вызов callback

Загрузка данных из бэкэнда происходит по этой команде
@load("/items.json")

она получает, и согласно расширению - автоматически парсит данные,
далее идёт ".then"

@load("/items.json").then((items) ->
context.items = items
).then callback

Это механизм приведения асинхронных запросов, к синхронному - в метод
then передаётся функция, которая получает параметр. И она будет
вызвана только после завершения асинхронного запроса, и в параметры к
ней будет передан результат функции - в нашем примере это будет
распарсенный json.

И значение присваивается в контекст (context.items = items) - и дальше
к нему обращаются из роутеров (@items)

Кстати в самом вверху, инициализация:
app = $.sammy("#main", ->
и здесь "#main" - это элемент в контексте которого app отображает
данные.

и строка :
context.app.swap ""
очищает содержимое этого элемента.

далее рендеринг шаблонов:
context.render("/item.haml",
id: i
item: item
)
возвращает dom элемент, который получился после обработки haml шаблона
item.haml, в контекст которого был передан хэш массив с ключами id и
item, вот содержимое haml шаблона:

.item
.item-image
%a{ href: "#/item/#{id}"}
%img{ alt: item.title, src: item.image}/
.item-artist= item.artist
.item-title= item.title
.item-price
$#{item.price}

Так же обратим внимание, что вверху подключены 2 плагина:
@use "Haml"
@use "Session"

предварительно были подключены соотв. js файлы в layout.haml:
sammy.haml.js
sammy.json.js
sammy.storage.js - содержит Session, и требует json плагин.

Session - обёртка над хранением данных - используется html5 storage,
если недоступен то куки, иначе в памяти.

Есть событийная модель, для этого определятся функция (обновляет
отображение корзины):

@bind "update-cart", ->


И далее она может быть вызвана с помощью @trigger, например:

@trigger "update-cart"
(вызывается в метода добавления пункта)

и так же:
@bind "run", ->
@trigger "update-cart"

Здесь "run" - это системное событие самого SammyJS - которое
вызывается при запуске (активации приложения), и соотв. в нём
происходит запуск события на обновление содержимого карзины.

Ну вот если кратко.

И для деплоя на CloudFoundry, надо:
1. получить аккаунт (бесплатно, при регистрации почтового ящика на
Cloudfoundry.com)
2. установить vmc - gem install vmc
3. настроить целевое облако
vmc target api.cloudfoundry.com
4. авторизоваться
vmc login
указать почту, и полученный по почте пароль
5. из папки приложения сделать
vmc push NAME_APP
NAME_APP - как вы назовёте приложение, в моём примере это было
"sammyjs-coffee-json-store" - будет создан домен 3го уровня
sammyjs-coffee-json-store.cloudfoundry.com
6. на все вопросы можно ответить по-умолчанию - приложение будет
запаковано и передано на cloudfoudnry - там распаковано, и стартовано.
7. для внесения изменения, надо находясь в корне приложения:
vmc update NAME_APP
система сама вычислит изменнения - запакует, запишет, и перезапустить
на сервере.


С уважением,
Илья

Reply all
Reply to author
Forward
0 new messages