Алексей Плуталов, Злые Марсиане
Книга «Getting Real» → Ruby on Rails
form ng-controller="Calculator"
input type="number" ng-model="a"
input type="number" ng-model="b"
Sum: {{sum}}
Обзор data-binding в Angular и Ember.js: bit.ly/1bOeL2f
.m-popup.sk-sign-in@@popup
.o-icon.sk-close@closeButton
/ эквивалентно
.m-popup.sk-sign-in data-block="popup"
.o-icon.sk-close data-role="closeButton"
evil.block "@@popup",
init: ->
@adaptToScreen()
@@blockName
транслируется в [data-block=blockName]
.
evil.block "@@popup",
open: ->
@el.addClass("is-opened")
close: ->
@el.removeClass("is-opened")
@el
ссылается на jQuery-объект текущей ноды.
.m-popup.sk-sign-in-up@@popup
.o-icon.sk-close@closeButton
form.st-sign-in-form@form@signInForm
form.st-sign-up-form@form@signUpForm
Для простоты, поля формы опущены, а сама форма упрощена.
evil.block "@@popup",
"on open": ->
@open()
"on close": ->
@close()
События, как внешнее API, сильно снижают code coupling.
evil.block "@@popup",
"ajax:beforeSend on @form": (e) ->
e.el.find("::submit").addClass("is-inactive")
"ajax:complete on @form": (e) ->
e.el.find("::submit").removeClass("is-inactive")
Источник события привязывается к event.el
.
evil.block "@@popup",
"sign-in on body": ->
@switchToSignInForm() and @open()
"sign-up on body": ->
@switchToSignUpForm() and @open()
$("body")
выступает в роли event channel
.
evil.block "@@popup",
"resize on window": ->
@adaptToScreen()
"message on window": (e, message) ->
if @checkMessageDomain(message)
@processMessage(message)
.m-popup.sk-sign-in-up@@popup@@closable
.o-icon.sk-close@closeButton
form.st-sign-in-form@@remoteForm@signInForm
form.st-sign-up-form@@remoteForm@signUpForm
evil.block "@@remoteForm",
"ajax:success": ->
@el.trigger("sent")
evil.block "@@popup",
"sent on @signInForm, @signUpForm": ->
@close()
evil.block "@@popup",
open: ->
$("body").trigger("close"); @show()
evil.block "@@popup",
open: ->
$("@@popup").trigger("close"); @show()
evil.block "@@closeable",
"click on @closeButton": ->
@el.trigger("close")
evil.block "@@popup",
"on close": ->
@close()
evil.block "@@commentBox",
"click on @commentButton": ->
@commentForm.addClass("is-opened")
На сервере заранее формируется нужный HTML. На клиенте производится только переключение его видимости.
evil.block "@@commentBox",
"ajax:success on @commentForm": (e, reply) ->
replyEl = $(reply).appendTo(@replies)
evil.block.vitalize(replyEl)
С сервера вместо JSON отправляется готовый HTML, с последующей инъекцией на страницу.
evil.block "@@commentBox",
"ajax:success on @commentForm": (e, reply) ->
replyHtml = JST["comment"](reply)
replyEl = $(replyHtml).appendTo(@replies)
evil.block.vitalize(replyEl)
Классический пример рендеринга на клиенте.
evil.block "@@react",
init: ->
cmpName = @el.data("react-component")
cmpData = @el.data("react-data") || { }
React.renderComponent(
evil.components[cmpName](cmpData), @el.get(0)
)
ui
и data
;