Rails & Javascript
Faça isso direito!
Dicas de como organizar o
javascript em apps Rails não SPA
$ whoami
• Cezinha Anjos.
• Comecei programando num
Apple II e gravando
programas em fitas cassetes
há 26 anos atrás.
• Atu...
• Estamos localizados em Tijucas - SC
- 40 km de Florianópolis.
• Somos em torno de 20 pessoas.
• Quase nenhuma verticaliz...
História desta palestra
História desta palestra
Hands on de 9 horas
História desta palestra
Hands on de 9 horas
Talk de 50 minutos
Qual o formato da
palestra?
Dicas
Partiremos de um app
tradicional Rails
Evoluindo o código
usando cada dica
Use o Gemfile somente
para dependências do
backend
01
(sempre que possível)
# Arquivo: Gemfile
source 'https://rubygems.org'
 
gem 'rails', '4.2.0'
gem 'sqlite3'
gem 'sass-rails', '~> 5.0'
gem 'ugli...
Use o Bower para as
dependências do
front-end
02
$ npm install -g bower
Instalação
Configuração
$ bower init
# enter, enter, enter, enter…
# até que o arquivo bower.json
# seja gerado
Configuração
// Arquivo: bower.json
{
name: ‘rails-and-js’,
version: '0.0.0',
authors: [
'Cezinha <cesar@asseinfo.com.br>'
...
Configuração
$ vim .bowerrc
{
"directory": "vendor/assets/bower"
}
Caminho onde os
pacotes serão baixados
e a asset pipelin...
Instalando dependências
$ bower install jquery#2.0.3 —-save
$ bower install jquery-ujs#1.0.3 --save
# Arquivo: Gemfile
......
Instalando dependências
// arquivo: bower.json
 
{
"name": "rails-and-js",
"version": "0.0.0",
"authors": [
"Cezinha <cesa...
Ajustando o manifesto
// arquivo: application.js
 
//= require jquery
//= require_tree .
//= require jquery_ujs//= require...
Você pode instalar
coisas como:
• JQuery;
• JQuery UI;
• Twitter Bootstrap;
• Font Awesome;
• Angular JS;
• Backbone;
• Re...
Crie uma pasta para cada
view e pelo menos um
arquivo para cada action
03
$ mkdir app/assets/javascripts/views
$ mkdir app/assets/javascripts/views/people
Uma pasta por view
Pelo menos um
arquivo ...
A separação dos scripts
ajudará nas futuras
manutenções
Aceite que todos os seus
javascripts acabarão em
um único arquivo
04
(nem sempre isso é verdade ;-)
Visão do programador
4 arquivos separados
// arquivo: app/assets/javascripts/views/people/index.js
 
alert("Running index.js");
// arquivo: app/assets/javascripts/v...
http://localhost:3000/
people/new
http://localhost:3000/
people/new
1
2
3
4
http://localhost:3000/
people/new
1
2
3
4
W
TF?!
// arquivo: application.js
// na visão do sprockets
// sem "uglificação"
 
alert("Running edit.js");
alert("Running index....
Você não tem como separar fisicamente
os scripts sem aumentar o número de
requisições.
Minha opinião: não separe!
O segredo é
modularizar
05
http://larsjung.de/modulejs/
Instalação
$ bower install modulejs#1.5.0 --save
Ajustando o manifesto
// arquivo: application.js
 
//= require jquery
//= require jquery-ujs
//= require_tree .//= require...
alert("Running index.js");
// arquivo: app/assets/javascripts/views/people/index.js
modulejs.define("people.index", functi...
Estabeleça um Single
Entry Point
06
Defina um único ponto
para início de
execução de todo o
seu javascript.
O fluxo de execução
tende a ficar mais
claro.
Carregamento
da página
Executa JS de
terceiros
Dispatcher
(boot.js)
people/index.js
foo.js
people/new.js people/edit.js pe...
Carregamento
da página
Executa JS de
terceiros
Dispatcher
(boot.js)
people/index.js
foo.js
people/new.js people/edit.js pe...
Carregamento
da página
Executa JS de
terceiros
Dispatcher
(boot.js)
people/index.js
foo.js
people/new.js people/edit.js pe...
Carregamento
da página
Executa JS de
terceiros
Dispatcher
(boot.js)
people/index.js
foo.js
people/new.js people/edit.js pe...
Carregamento
da página
Executa JS de
terceiros
Dispatcher
(boot.js)
people/index.js
foo.js
people/new.js people/edit.js pe...
Carregamento
da página
Executa JS de
terceiros
Dispatcher
(boot.js)
people/index.js
foo.js
people/new.js people/edit.js pe...
// arquivo app/assets/javascripts/boot.js
 
(function() {
"use strict";
 
$(document).ready(function() {
// Aqui deve ser ...
Ajustando o manifesto
// arquivo: application.js
 
//= require jquery
//= require jquery-ujs
//= require modulejs
//= requ...
// arquivo app/assets/javascripts/boot.js
 
(function() {
"use strict";
 
$(document).ready(function() {
});
})()
// Aqui ...
// arquivo app/assets/javascripts/boot.js
 
(function() {
"use strict";
 
$(document).ready(function() {
});
})()
// Aqui ...
// arquivo app/assets/javascripts/boot.js
 
(function() {
"use strict";
 
$(document).ready(function() {
});
})()
// Aqui ...
Use o Dispatcher para
executar o JS de cada
view
07
// arquivo app/assets/javascripts/boot.js
 
(function() {
"use strict";
 
$(document).ready(function() {
var mymodule = mo...
// arquivo app/assets/javascripts/boot.js
 
(function() {
"use strict";
 
$(document).ready(function() {
var mymodule = mo...
Desafio: como sinalizar
para o JS qual a action
que estamos executando?
Através do HTML gerado
pelo servidor.
<body dispatcher="people.index">
<body dispatcher="people.index">
<!-- arquivo:
app/views/layouts/application.html.erb
-->
 
<body <%= dispatcher_tag %>>
<body dispatcher="people.index">
<!-- arquivo:
app/views/layouts/application.html.erb
-->
 
<body <%= dispatcher_tag %>>
C...
<body dispatcher="people.index">
# arquivo: app/helpers/application_helper.rb
 
module ApplicationHelper
def dispatcher_ta...
<body dispatcher="people.index">
# arquivo: app/helpers/application_helper.rb
 
module ApplicationHelper
def dispatcher_ta...
// arquivo app/assets/javascripts/boot.js
 
(function() {
"use strict";
 
$(document).ready(function() {
var mymodule = mo...
// arquivo app/assets/javascripts/boot.js
 
(function() {
"use strict";
 
$(document).ready(function() {
var mymodule = mo...
// arquivo app/assets/javascripts/boot.js
 
(function() {
"use strict";
 
$(document).ready(function() {
var mymodule = mo...
// arquivo app/assets/javascripts/boot.js
 
(function() {
"use strict";
 
$(document).ready(function() {
var mymodule = mo...
// arquivo app/assets/javascripts/boot.js
 
(function() {
"use strict";
 
$(document).ready(function() {
var mymodule = mo...
Faça seus controllers
responderem JSON
08
# arquivo: app/controllers/people_controller.rb
 
...
def index
@people = Person.all
 
respond_to do |format|
format.html
...
respond_with foi removido
do Rails na versão 4.2.
IMHO respond_to deixa
mais claro a intenção do
programador.
ActiveModel::Serializers
Existe coisa melhor do
que to_json
09
class PostSerializer < ActiveModel::Serializer
attributes :title, :body
has_many :comments
end
class CommentSerializer < A...
[
{
"title":"Obama mentiu sobre operação que matou Bin Laden",
"body":"O jornalista Seymour Hersh, que recebeu o Prêmio Pu...
js-routes: Named
Routes do Rails no JS
10
Rails.application.routes.draw do
resources :people
end
people GET /people(.:format) people#index
new_person GET /people/ne...
# Arquivo: Gemfile
source 'https://rubygems.org'
 
gem 'rails', '4.2.0'
gem 'sqlite3'
gem 'sass-rails', '~> 5.0'
gem 'ugli...
//= require_tree ./views
//= require boot
//= require js-routes
//= require_tree ./views
//= require boot
Ajustando o mani...
Routes.people_path()
"/people.json"
 
Routes.new_person_path()
"/people/new.json"
 
Routes.edit_person_path(1)
"/people/1/...
var promise;
 
promise = $.get("/people.json");
✘
promise = $.get(Routes.people_path());
✔
ejs: fazendo o sprockets
servir templates
11
# Arquivo: Gemfile
source 'https://rubygems.org'
 
gem 'rails', '4.2.0'
gem 'sqlite3'
gem 'sass-rails', '~> 5.0'
gem 'ugli...
Ajustando o manifesto
//= require_tree ./views
//= require boot
//= require_tree ./templates
//= require_tree ./views
//= ...
<!-- arquivo:
app/assets/javascripts/templates/people/example.jst.ejs
-->
 
<p>Name:</p>
<p><%= name %></p>
 
<p>Phone:</p...
(function() {
"use strict"
var html = JST["templates/people/example"]({
name: "The name",
phone: "(48) 1234-5678"
});
$("d...
(function() {
"use strict"
var html = JST["templates/people/example"]({
name: "The name",
phone: "(48) 1234-5678"
});
$("d...
(function() {
"use strict"
var html = JST["templates/people/example"]({
name: "The name",
phone: "(48) 1234-5678"
});
$("d...
(function() {
"use strict"
var html = JST["templates/people/example"]({
name: "The name",
phone: "(48) 1234-5678"
});
$("d...
(function() {
"use strict"
var html = JST["templates/people/example"]({
name: "The name",
phone: "(48) 1234-5678"
});
$("d...
(function() {
"use strict"
var html = JST["templates/people/example"]({
name: "The name",
phone: "(48) 1234-5678"
});
$("d...
Crie escopos com IIFE
12
IIFE
Immediately-invoked
function expression
(expressão de função invocada
imediatamente)
IIFE pode ser usada para
isolar escopos
 
(function() {
}())
Immediately-invoked function expression
 
(function() {
}())
Expressão
Immediately-invoked function expression
 
(function() {
}())
Função
Immediately-invoked function expression
 
(function() {
}())
Execução imediata
Immediately-invoked function expression
var foo = "value outside IIFE";
 
(function() {
var foo = "value inside IIFE";
console.log(foo);
}())
 
console.log(foo);
...
Lembre-se que todos os
seus javascripts acabarão
em um único arquivo.
Sem escopos os
resultados da "uglificação"
são imprevisíveis.
Na boa… “use strict"
13
(function () {
"use strict";
// Introduzido no ECMA 5.
// Converte enganos em erros.
// Simplifica o uso de variáveis.
// ...
(function () {
foo = "this should be a private content";
}())
Falta do "var" fará de "foo" global
Falta do “use strict" fa...
(function () {
foo = "this should be a private content";
}())
"use strict";
ReferenceError: Can’t find variable foo
(function () {
foo = "this should be a private content";
}())
"use strict";
var foo = "this should be a private content";
Fuja do callback hell
use promises
14
var promise;
 
promise = $.get("/people.json");
 
promise.done(function(data) {
alert("done");
alert(JSON.stringify(data))...
So long, and thanks for all
the fish!
@cezinha_anjos
cezinha.info
asseinfo.com.br
111
TDC 2015 - Rails & Javascript: faça isso direito
TDC 2015 - Rails & Javascript: faça isso direito
TDC 2015 - Rails & Javascript: faça isso direito
TDC 2015 - Rails & Javascript: faça isso direito
Próximos SlideShares
Carregando em…5
×

TDC 2015 - Rails & Javascript: faça isso direito

519 visualizações

Publicada em

Este talk propõe mostrar para você como construir um app Rails (não SPA) com uma estrutura organizada de Javascript. Você terá oportunidade de ver conceitos como injeção de dependência, single point entry, dispatcher, promises, IIFE, templates JS, Named Routes JS e muito mais? tudo isso aplicado na prática (e tudo junto). Chega de produzir brown fileds! Faça você também a coisa certa.

Publicada em: Software
0 comentários
0 gostaram
Estatísticas
Notas
  • Seja o primeiro a comentar

  • Seja a primeira pessoa a gostar disto

Sem downloads
Visualizações
Visualizações totais
519
No SlideShare
0
A partir de incorporações
0
Número de incorporações
11
Ações
Compartilhamentos
0
Downloads
11
Comentários
0
Gostaram
0
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide

TDC 2015 - Rails & Javascript: faça isso direito

  1. 1. Rails & Javascript Faça isso direito! Dicas de como organizar o javascript em apps Rails não SPA
  2. 2. $ whoami • Cezinha Anjos. • Comecei programando num Apple II e gravando programas em fitas cassetes há 26 anos atrás. • Atualmente focado em Ruby on Rails e Javascript. • Gosto de OO, Clean Code, Design Patterns, BDD e Lean. • Diretor da ASSEINFO.
  3. 3. • Estamos localizados em Tijucas - SC - 40 km de Florianópolis. • Somos em torno de 20 pessoas. • Quase nenhuma verticalização hierárquica. Quem tem chefe é índio! • Desde 2001 no mercado de automação comercial. • Trabalhamos com ERP. • Foco em qualidade. • Já nascemos agile, mesmo antes de conhecer o manifesto ágil. 3
  4. 4. História desta palestra
  5. 5. História desta palestra Hands on de 9 horas
  6. 6. História desta palestra Hands on de 9 horas Talk de 50 minutos
  7. 7. Qual o formato da palestra?
  8. 8. Dicas
  9. 9. Partiremos de um app tradicional Rails
  10. 10. Evoluindo o código usando cada dica
  11. 11. Use o Gemfile somente para dependências do backend 01 (sempre que possível)
  12. 12. # Arquivo: Gemfile source 'https://rubygems.org'   gem 'rails', '4.2.0' gem 'sqlite3' gem 'sass-rails', '~> 5.0' gem 'uglifier', '>= 1.3.0' gem 'coffee-rails', '~> 4.1.0' gem 'jquery-rails' Remover gems do front-end
  13. 13. Use o Bower para as dependências do front-end 02
  14. 14. $ npm install -g bower Instalação
  15. 15. Configuração $ bower init # enter, enter, enter, enter… # até que o arquivo bower.json # seja gerado
  16. 16. Configuração // Arquivo: bower.json { name: ‘rails-and-js’, version: '0.0.0', authors: [ 'Cezinha <cesar@asseinfo.com.br>' ], license: 'MIT', ignore: [ '**/.*', 'node_modules', 'bower_components', 'test', 'tests' ] }
  17. 17. Configuração $ vim .bowerrc { "directory": "vendor/assets/bower" } Caminho onde os pacotes serão baixados e a asset pipeline poderá utilizar.
  18. 18. Instalando dependências $ bower install jquery#2.0.3 —-save $ bower install jquery-ujs#1.0.3 --save # Arquivo: Gemfile ... gem 'jquery-rails'
  19. 19. Instalando dependências // arquivo: bower.json   { "name": "rails-and-js", "version": "0.0.0", "authors": [ "Cezinha <cesar@asseinfo.com.br>" ], "license": "MIT", "ignore": [ "**/.*", "node_modules", "bower_components", "test", "tests" ], "dependencies": { "jquery": "2.0.3", "jquery-ujs": "1.0.3" } }
  20. 20. Ajustando o manifesto // arquivo: application.js   //= require jquery //= require_tree . //= require jquery_ujs//= require jquery-ujs
  21. 21. Você pode instalar coisas como: • JQuery; • JQuery UI; • Twitter Bootstrap; • Font Awesome; • Angular JS; • Backbone; • React JS; Qualquer projeto que esteja no github (ou sim ilar)
  22. 22. Crie uma pasta para cada view e pelo menos um arquivo para cada action 03
  23. 23. $ mkdir app/assets/javascripts/views $ mkdir app/assets/javascripts/views/people Uma pasta por view Pelo menos um arquivo por action
  24. 24. A separação dos scripts ajudará nas futuras manutenções
  25. 25. Aceite que todos os seus javascripts acabarão em um único arquivo 04 (nem sempre isso é verdade ;-)
  26. 26. Visão do programador 4 arquivos separados
  27. 27. // arquivo: app/assets/javascripts/views/people/index.js   alert("Running index.js"); // arquivo: app/assets/javascripts/views/people/edit.js   alert("Running edit.js"); // arquivo: app/assets/javascripts/views/people/show.js   alert("Running show.js"); // arquivo: app/assets/javascripts/views/people/new.js   alert("Running new.js");
  28. 28. http://localhost:3000/ people/new
  29. 29. http://localhost:3000/ people/new 1 2 3 4
  30. 30. http://localhost:3000/ people/new 1 2 3 4 W TF?!
  31. 31. // arquivo: application.js // na visão do sprockets // sem "uglificação"   alert("Running edit.js"); alert("Running index.js"); alert("Running new.js"); alert("Running show.js"); Visão do sprockets
  32. 32. Você não tem como separar fisicamente os scripts sem aumentar o número de requisições. Minha opinião: não separe!
  33. 33. O segredo é modularizar 05
  34. 34. http://larsjung.de/modulejs/
  35. 35. Instalação $ bower install modulejs#1.5.0 --save
  36. 36. Ajustando o manifesto // arquivo: application.js   //= require jquery //= require jquery-ujs //= require_tree .//= require modulejs //= require_tree .
  37. 37. alert("Running index.js"); // arquivo: app/assets/javascripts/views/people/index.js modulejs.define("people.index", function() { return function() { alert("Running index.js”); }; }); // Resultado do console: function () { alert("Running index.js"); } 1 2 3 4 var mymodule = modulejs.require("people.index"); console.log(mymodule); mymodule();
  38. 38. Estabeleça um Single Entry Point 06
  39. 39. Defina um único ponto para início de execução de todo o seu javascript.
  40. 40. O fluxo de execução tende a ficar mais claro.
  41. 41. Carregamento da página Executa JS de terceiros Dispatcher (boot.js) people/index.js foo.js people/new.js people/edit.js people/show.js bar.js x.js y.js Fluxo de execução
  42. 42. Carregamento da página Executa JS de terceiros Dispatcher (boot.js) people/index.js foo.js people/new.js people/edit.js people/show.js bar.js x.js y.js Fluxo de execução
  43. 43. Carregamento da página Executa JS de terceiros Dispatcher (boot.js) people/index.js foo.js people/new.js people/edit.js people/show.js bar.js x.js y.js Fluxo de execução
  44. 44. Carregamento da página Executa JS de terceiros Dispatcher (boot.js) people/index.js foo.js people/new.js people/edit.js people/show.js bar.js x.js y.js Fluxo de execução
  45. 45. Carregamento da página Executa JS de terceiros Dispatcher (boot.js) people/index.js foo.js people/new.js people/edit.js people/show.js bar.js x.js y.js Fluxo de execução
  46. 46. Carregamento da página Executa JS de terceiros Dispatcher (boot.js) people/index.js foo.js people/new.js people/edit.js people/show.js bar.js x.js y.js Fluxo de execução
  47. 47. // arquivo app/assets/javascripts/boot.js   (function() { "use strict";   $(document).ready(function() { // Aqui deve ser o seu primeiro // ponto de execução de javascript }); })()
  48. 48. Ajustando o manifesto // arquivo: application.js   //= require jquery //= require jquery-ujs //= require modulejs //= require_tree . //= require boot //= require_tree ./views
  49. 49. // arquivo app/assets/javascripts/boot.js   (function() { "use strict";   $(document).ready(function() { }); })() // Aqui deve ser o seu primeiro // ponto de execução de javascript // modulejs.define("people.index", function() { return function() { alert("Running index.js") }; }); // arquivo: app/assets/javascripts/views/people/index.js var mymodule = modulejs.require("people.index"); console.log(mymodule); mymodule();
  50. 50. // arquivo app/assets/javascripts/boot.js   (function() { "use strict";   $(document).ready(function() { }); })() // Aqui deve ser o seu primeiro // ponto de execução de javascript // modulejs.define("people.index", function() { return function() { alert("Running index.js") }; }); // arquivo: app/assets/javascripts/views/people/index.js var mymodule = modulejs.require("people.index"); console.log(mymodule); mymodule();
  51. 51. // arquivo app/assets/javascripts/boot.js   (function() { "use strict";   $(document).ready(function() { }); })() // Aqui deve ser o seu primeiro // ponto de execução de javascript // modulejs.define("people.index", function() { return function() { alert("Running index.js") }; }); // arquivo: app/assets/javascripts/views/people/index.js var mymodule = modulejs.require("people.index"); console.log(mymodule); mymodule(); var mymodule = modulejs.require("people.index"); console.log(mymodule); mymodule();
  52. 52. Use o Dispatcher para executar o JS de cada view 07
  53. 53. // arquivo app/assets/javascripts/boot.js   (function() { "use strict";   $(document).ready(function() { var mymodule = modulejs.require("people.index"); console.log(mymodule); mymodule(); }); })()
  54. 54. // arquivo app/assets/javascripts/boot.js   (function() { "use strict";   $(document).ready(function() { var mymodule = modulejs.require("people.index"); console.log(mymodule); mymodule(); }); })() A action está hard coded neste ponto!
  55. 55. Desafio: como sinalizar para o JS qual a action que estamos executando?
  56. 56. Através do HTML gerado pelo servidor.
  57. 57. <body dispatcher="people.index">
  58. 58. <body dispatcher="people.index"> <!-- arquivo: app/views/layouts/application.html.erb -->   <body <%= dispatcher_tag %>>
  59. 59. <body dispatcher="people.index"> <!-- arquivo: app/views/layouts/application.html.erb -->   <body <%= dispatcher_tag %>> Criaremos um helper para “batizar" a tag body
  60. 60. <body dispatcher="people.index"> # arquivo: app/helpers/application_helper.rb   module ApplicationHelper def dispatcher_tag controller_name = controller.class.name.underscore controller_name.gsub!(///, "_") controller_name.gsub!(/_controller$/, "")   div_tag = %(dispatcher="#{controller_name}.#{controller.action_name}")   div_tag.html_safe end end
  61. 61. <body dispatcher="people.index"> # arquivo: app/helpers/application_helper.rb   module ApplicationHelper def dispatcher_tag controller_name = controller.class.name.underscore controller_name.gsub!(///, "_") controller_name.gsub!(/_controller$/, "")   div_tag = %(dispatcher="#{controller_name}.#{controller.action_name}")   div_tag.html_safe end end
  62. 62. // arquivo app/assets/javascripts/boot.js   (function() { "use strict";   $(document).ready(function() { var mymodule = modulejs.require("people.index"); console.log(mymodule); mymodule(); }); })() A action está hard coded neste ponto! <body dispatcher="people.index">
  63. 63. // arquivo app/assets/javascripts/boot.js   (function() { "use strict";   $(document).ready(function() { var mymodule = modulejs.require("people.index"); console.log(mymodule); mymodule(); }); })() <body dispatcher="people.index"> var dispatch_to = $("body").attr("dispatcher");
  64. 64. // arquivo app/assets/javascripts/boot.js   (function() { "use strict";   $(document).ready(function() { var mymodule = modulejs.require("people.index"); console.log(mymodule); mymodule(); }); })() <body dispatcher="people.index"> var dispatch_to = $("body").attr("dispatcher");
  65. 65. // arquivo app/assets/javascripts/boot.js   (function() { "use strict";   $(document).ready(function() { var mymodule = modulejs.require(dispatch_to); console.log(mymodule); mymodule(); }); })() <body dispatcher="people.index"> var dispatch_to = $("body").attr("dispatcher");
  66. 66. // arquivo app/assets/javascripts/boot.js   (function() { "use strict";   $(document).ready(function() { var mymodule = modulejs.require(dispatch_to); console.log(mymodule); mymodule(); }); })() <body dispatcher="people.index"> var dispatch_to = $("body").attr("dispatcher");
  67. 67. Faça seus controllers responderem JSON 08
  68. 68. # arquivo: app/controllers/people_controller.rb   ... def index @people = Person.all   respond_to do |format| format.html format.json { render json: @people.to_json } end end ...
  69. 69. respond_with foi removido do Rails na versão 4.2.
  70. 70. IMHO respond_to deixa mais claro a intenção do programador.
  71. 71. ActiveModel::Serializers Existe coisa melhor do que to_json 09
  72. 72. class PostSerializer < ActiveModel::Serializer attributes :title, :body has_many :comments end class CommentSerializer < ActiveModel::Serializer attributes :name, :body belongs_to :post end
  73. 73. [ { "title":"Obama mentiu sobre operação que matou Bin Laden", "body":"O jornalista Seymour Hersh, que recebeu o Prêmio Pulitzer…”, "comments": [ { "name":"Fulano", "body":"Eu não acredito!" } ] } ]
  74. 74. js-routes: Named Routes do Rails no JS 10
  75. 75. Rails.application.routes.draw do resources :people end people GET /people(.:format) people#index new_person GET /people/new(.:format) people#new edit_person GET /people/:id/edit(.:format) people#edit person GET /people/:id(.:format) people#show $ bin/rake routes ✔ ✘
  76. 76. # Arquivo: Gemfile source 'https://rubygems.org'   gem 'rails', '4.2.0' gem 'sqlite3' gem 'sass-rails', '~> 5.0' gem 'uglifier', '>= 1.3.0' gem 'coffee-rails', '~> 4.1.0’ gem 'jquery-rails' gem 'js-routes'
  77. 77. //= require_tree ./views //= require boot //= require js-routes //= require_tree ./views //= require boot Ajustando o manifesto // arquivo: application.js   //= require jquery //= require jquery-ujs //= require modulejs
  78. 78. Routes.people_path() "/people.json"   Routes.new_person_path() "/people/new.json"   Routes.edit_person_path(1) "/people/1/edit.json"   Routes.person_path(1) "/people/1.json"
  79. 79. var promise;   promise = $.get("/people.json"); ✘ promise = $.get(Routes.people_path()); ✔
  80. 80. ejs: fazendo o sprockets servir templates 11
  81. 81. # Arquivo: Gemfile source 'https://rubygems.org'   gem 'rails', '4.2.0' gem 'sqlite3' gem 'sass-rails', '~> 5.0' gem 'uglifier', '>= 1.3.0' gem 'coffee-rails', '~> 4.1.0’ gem 'jquery-rails' gem 'js-routes' gem 'ejs'
  82. 82. Ajustando o manifesto //= require_tree ./views //= require boot //= require_tree ./templates //= require_tree ./views //= require boot // arquivo: application.js   //= require jquery //= require jquery-ujs //= require modulejs //= require js-routes
  83. 83. <!-- arquivo: app/assets/javascripts/templates/people/example.jst.ejs -->   <p>Name:</p> <p><%= name %></p>   <p>Phone:</p> <p><%= phone %></p> Criando um template
  84. 84. (function() { "use strict" var html = JST["templates/people/example"]({ name: "The name", phone: "(48) 1234-5678" }); $("div#person").html(html); }()) Consumindo um template <p>Name:</p> <p><%= name %></p>   <p>Phone:</p> <p><%= phone %></p>
  85. 85. (function() { "use strict" var html = JST["templates/people/example"]({ name: "The name", phone: "(48) 1234-5678" }); $("div#person").html(html); }()) Consumindo um template <p>Name:</p> <p><%= name %></p>   <p>Phone:</p> <p><%= phone %></p> Array de templates compilados
  86. 86. (function() { "use strict" var html = JST["templates/people/example"]({ name: "The name", phone: "(48) 1234-5678" }); $("div#person").html(html); }()) Consumindo um template <p>Name:</p> <p><%= name %></p>   <p>Phone:</p> <p><%= phone %></p> A chave do array é o path do template
  87. 87. (function() { "use strict" var html = JST["templates/people/example"]({ name: "The name", phone: "(48) 1234-5678" }); $("div#person").html(html); }()) Consumindo um template <p>Name:</p> <p><%= name %></p>   <p>Phone:</p> <p><%= phone %></p> O conteúdo do array é uma função
  88. 88. (function() { "use strict" var html = JST["templates/people/example"]({ name: "The name", phone: "(48) 1234-5678" }); $("div#person").html(html); }()) Consumindo um template <p>Name:</p> <p><%= name %></p>   <p>Phone:</p> <p><%= phone %></p> Objeto literal com parâmetros do template
  89. 89. (function() { "use strict" var html = JST["templates/people/example"]({ name: "The name", phone: "(48) 1234-5678" }); $("div#person").html(html); }()) Consumindo um template <p>Name:</p> <p><%= name %></p>   <p>Phone:</p> <p><%= phone %></p> Use o html resul- tante como quiser
  90. 90. Crie escopos com IIFE 12
  91. 91. IIFE Immediately-invoked function expression (expressão de função invocada imediatamente)
  92. 92. IIFE pode ser usada para isolar escopos
  93. 93.   (function() { }()) Immediately-invoked function expression
  94. 94.   (function() { }()) Expressão Immediately-invoked function expression
  95. 95.   (function() { }()) Função Immediately-invoked function expression
  96. 96.   (function() { }()) Execução imediata Immediately-invoked function expression
  97. 97. var foo = "value outside IIFE";   (function() { var foo = "value inside IIFE"; console.log(foo); }())   console.log(foo); // Resultado: // value inside IIFE // value outside IIFE
  98. 98. Lembre-se que todos os seus javascripts acabarão em um único arquivo.
  99. 99. Sem escopos os resultados da "uglificação" são imprevisíveis.
  100. 100. Na boa… “use strict" 13
  101. 101. (function () { "use strict"; // Introduzido no ECMA 5. // Converte enganos em erros. // Simplifica o uso de variáveis. // Simplifica "eval" e argumentos. // Ajuda a escrever JS mais seguro. // // Referência: Mozilla Developer Network }())
  102. 102. (function () { foo = "this should be a private content"; }()) Falta do "var" fará de "foo" global Falta do “use strict" fará não gerar erro
  103. 103. (function () { foo = "this should be a private content"; }()) "use strict"; ReferenceError: Can’t find variable foo
  104. 104. (function () { foo = "this should be a private content"; }()) "use strict"; var foo = "this should be a private content";
  105. 105. Fuja do callback hell use promises 14
  106. 106. var promise;   promise = $.get("/people.json");   promise.done(function(data) { alert("done"); alert(JSON.stringify(data)); });   promise.fail(function(error) { alert("fail"); alert("status text:" + error.statusText); });   promise.always(function() { alert("always"); });
  107. 107. So long, and thanks for all the fish! @cezinha_anjos cezinha.info asseinfo.com.br 111

×