z, ? | toggle help (this) |
space, → | next slide |
shift-space, ← | previous slide |
d | toggle debug mode |
## <ret> | go to slide # |
c, t | table of contents (vi) |
f | toggle footer |
r | reload slides |
n | toggle notes |
p | run preshow |
P | toggle pause |
server {
listen 80;
server_name localhost;
location / {
root .../bcmvc/lib/bcmvc_web/priv/;
if ($request_method ~* POST) {
proxy_pass http://localhost:8080;
}
if ($http_accept ~* application/json) {
proxy_pass http://localhost:8080;
}
}
}
├── coffee
│ └── app.coffee
├── controllers
│ └── todos_controller.coffee
├── index.html
├── models
│ └── todo.coffee
<li data-foreach-todo="Todo.all"
data-event-doubleclick="controllers.todos.edit"
data-addclass-completed="todo.isDone">
<div class="view">
<input class="toggle"
type="checkbox" data-bind="todo.isDone" />
<label data-bind="todo.body" />
<button class="destroy"
data-event-click="todo.destroy"></button>
</div>
<input data-bind-id="todo.id" class="edit"
data-bind-value="todo.body"
data-event-submit="controllers.todos.update">
</li>
class TodoMVC.Todo extends Batman.Model
@persist TodoMVC.JSONRestStorage
@encode 'body', 'isDone'
body: ''
isDone: false
class TodoMVC.TodosController extends Batman.Controller
index: ->
@set 'emptyTodo', new Todo
@render false
create: =>
@todo.save =>
@set 'emptyTodo', new Todo
edit: (node, event) ->
$(node).addClass('editing')
update: (node, event) ->
newTodo = new Todo({id: $(node).attr('id'), body: $(node).val()})
newTodo.save()
$(node).parent().removeClass('editing')
POST:
/todos/
{body:"bane wants to meet, not worried",isDone:false}
PUT:
/todos/33e93b30-2371-4071-afc5-2d48226d5dba
{body:"bane wants to meet, not worried",isDone:false}
GET:
/todos/
[{id:"33e93b30-2371-4071-afc5-2d48226d5dba",
body:"bane wants to meet, not worried",
isDone:false}]
DELETE:
/todos/33e93b30-2371-4071-afc5-2d48226d5dba
├── lib
│ ├── bcmvc_db
│ │ └── src
│ │ ├── bcmvc_db_app.erl
│ │ ├── bcmvc_db.app.src
│ │ ├── bcmvc_db.erl
│ │ ├── bcmvc_db_mnesia.erl
│ │ ├── bcmvc_db_sup.erl
│ │ └── bcmvc_idioms.hrl
│ ├── bcmvc_models
│ │ └── src
│ │ ├── bcmvc_models.app.src
│ │ ├── bcmvc_model_todo.erl
│ │ ├── bcmvc_model_transform.erl
│ │ ├── bcmvc_model_types.erl
│ │ └── bcmvc_model_utils.erl
│ └── bcmvc_web
│ ├── priv
│ └── src
│ ├── bcmvc_todo_handler.erl
│ ├── bcmvc_web_app.erl
│ ├── bcmvc_web.app.src
│ ├── bcmvc_web_sup.erl
│ └── bcmvc_web_utils.erl
-compile({parse_transform, bcmvc_model_transform}).
-record(bcmvc_model_todo, {id = ossp_uuid:make(v1, text) :: string(),
body :: binary(),
isDone :: boolean()}).
find(Criteria) when is_list(Criteria) ->
bcmvc_db:find(?MODULE, Criteria);
find(Criteria) when is_tuple(Criteria)->
bcmvc_db:find(?MODULE, [Criteria]).
to_json(Record) ->
?record_to_json(?MODULE, Record).
to_record(JSON) ->
?json_to_record(?MODULE, JSON).
{[<<"todos">>], bcmvc_todo_handler, []}
{[<<"todos">>, todo], bcmvc_todo_handler, []}
init(_Transport, _Req, _Opts) ->
{upgrade, protocol, cowboy_http_rest}.
allowed_methods(Req, State) ->
{['HEAD', 'GET', 'PUT', 'POST', 'DELETE'], Req, State}.
content_types_accepted(Req, State) ->
{[{{<<"application">>, <<"json">>, []}, put_json}], Req, State}.
content_types_provided(Req, State) ->
{[{{<<"application">>, <<"json">>, []}, get_json}], Req, State}.
process_post(Req, State) ->
{ok, Body, Req1} = cowboy_http_req:body(Req),
Todo = bcmvc_model_todo:to_record(Body),
bcmvc_model_todo:save(Todo),
NewId = bcmvc_model_todo:get(id, Todo),
{ok, Req2} = cowboy_http_req:set_resp_header(
<<"Location">>, <<"/todos/", NewId/binary>>, Req1),
{true, Req1, State}.
put_json(Req, State) ->
{ok, Body, Req1} = cowboy_http_req:body(Req),
{TodoId, Req2} = cowboy_http_req:binding(todo, Req1),
Todo = bcmvc_model_todo:set(bcmvc_model_todo:to_record(Body), id, TodoId),
bcmvc_model_todo:update(Todo),
{true, Req2, State}.
get_json(Req, State) ->
All = [bcmvc_model_todo:to_json(Model) || Model <- bcmvc_model_todo:all()]
JsonModels = list_to_json(All),
{<<"[", JsonModels/binary, "]">>, Req, State}.
delete_resource(Req, State) ->
{TodoId, Req1} = cowboy_http_req:binding(todo, Req),
bcmvc_model_todo:delete(TodoId),
{true, Req1, State}.