SlideShare una empresa de Scribd logo
1 de 116
Descargar para leer sin conexión
Rails & Javascript
Faça isso direito!
Sacadas de como organizar seu 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.
• Atualmente focado em Ruby on Rails
e Javascript.
• CEO da ASSEINFO.
Rails & Javascript
Faça isso direito!
Sacadas de como organizar seu javascript
em apps Rails não SPA
Do que vamos falar?
// Caro mantenedor:
//
// Quando eu escrevi este código, somente eu
// e Deus sabíamos o que ele fazia.
// Agora somente Deus sabe!
//
// Então, se você está tentando “otimizar"
// esta rotina (e falhou!), por favor,
// incremente o contador a seguir como um aviso
// para o próximo cara:
//
// total_de_horas_gastas_aqui = 67
ORGANIZAÇÃO
App tradicional
Rails
Organizar o JS
Aplicar um
framework JS
Separar o
front-end do
back-end
App tradicional
Rails
Organizar o JS
Aplicar um
framework JS
Separar o
front-end do
back-end
App tradicional
Rails
Organizar o JS
Aplicar um
framework JS
Separar o
front-end do
back-end
App tradicional
Rails
Organizar o JS
Aplicar um
framework JS
Separar o
front-end do
back-end
App tradicional
Rails
Organizar o JS
Aplicar um
framework JS
Separar o
front-end do
back-end
Formato do talk
Sacadas
X
Use o Gemfile somente
para as dependências
do back-end
9901
Independência de um fornecedor
que encapsule a library
Maior domínio sobre o que você
quer incluir no seu app
# 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'
X
Use o bower para as
dependências do frontend
02
É o bundler do front-end
Virou padrão no mundo
front-end
Tudo que você imagina de front-
end é publicado no bower
E o que não está… basta
referenciar o github
// 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"
}
}
X
Crie uma pasta para cada
view e pelo menos um
arquivo para cada action
03
Uma pasta para
cada view
Pelo menos um
arquivo por action
Facilidade em localizar os
scripts
Evita a escrita de scripts
gigantescos
X
Aceite que todos os seus
javascripts acabarão em um
único arquivo
04
Visão do programador
4 arquivos separados
// 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");
// 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
Você não tem como separar os
scripts sem aumentar o número de
requisições.
X
O segredo é modularizar05
http://larsjung.de/modulejs/
modulejs.define("people.index", function() {
return function() {
"use string";
alert("Running index.js”);
};
});
modulejs.define("people.index", function() {
return function() {
"use string";
alert("Running index.js”);
};
});
modulejs.define("people.index", function() {
return function() {
"use string";
alert("Running index.js”);
};
});
modulejs.define("people.index", function() {
return function() {
"use string";
alert("Running index.js”);
};
});
modulejs.define("people.index", function() {
return function() {
"use string";
alert("Running index.js”);
};
});
modulejs.define("people.index", function() {
return function() {
"use string";
alert("Running index.js”);
};
});
var mymodule = modulejs.require("people.index");
console.log(mymodule);
mymodule();
modulejs.define("people.index", function() {
return function() {
"use string";
alert("Running index.js”);
};
});
var mymodule = modulejs.require("people.index");
console.log(mymodule);
mymodule();
modulejs.define("people.index", function() {
return function() {
"use string";
alert("Running index.js”);
};
});
var mymodule = modulejs.require("people.index");
console.log(mymodule);
mymodule();
// Resultado do console:
function () { "use string"; alert("Running index.js"); }
modulejs.define("people.index", function() {
return function() {
"use string";
alert("Running index.js”);
};
});
var mymodule = modulejs.require("people.index");
console.log(mymodule);
mymodule();
// Resultado do console:
function () { "use string"; alert("Running index.js"); }
X
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 people/show.js
bar.js
x.js y.js
Fluxo de
execução
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
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
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
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
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
// arquivo app/assets/javascripts/boot.js
 
(function() {
"use strict";
 
$(document).ready(function() {
// Aqui deve ser o seu primeiro
// ponto de execução de javascript
});
})()
X
Use um dispatcher para
executar o JS de cada view
07
Desafio: como sinalizar para o JS
qual action deve ser executada?
Resposta: através do HTML
gerado pelo servidor
<body dispatcher="people.index">
<body dispatcher="people.index">
Indicamos aqui qual JS deve ser executado
<body <%= dispatcher_tag %>>
<body <%= dispatcher_tag %>>
# 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
(function() {
"use strict";
 
$(document).ready(function() {
var dispatch_to = $("body").attr("dispatcher");
var mymodule = modulejs.require(dispatch_to);
mymodule();
});
})()
Single
Entry
Point
(function() {
"use strict";
 
$(document).ready(function() {
var dispatch_to = $("body").attr("dispatcher");
var mymodule = modulejs.require(dispatch_to);
mymodule();
});
})()
Single
Entry
Point
(function() {
"use strict";
 
$(document).ready(function() {
var dispatch_to = $("body").attr("dispatcher");
var mymodule = modulejs.require(dispatch_to);
mymodule();
});
})()
Single
Entry
Point
<body dispatcher="people.index">
(function() {
"use strict";
 
$(document).ready(function() {
var dispatch_to = $("body").attr("dispatcher");
var mymodule = modulejs.require(dispatch_to);
mymodule();
});
})()
Single
Entry
Point
function () { "use string"; alert("Running index.js"); }
(function() {
"use strict";
 
$(document).ready(function() {
var dispatch_to = $("body").attr("dispatcher");
var mymodule = modulejs.require(dispatch_to);
mymodule();
});
})()
Single
Entry
Point
X
js-routes: named routes do
Rails disponíveis no JS
08
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
✔
✘
var promise, id;
id = 1; 
promise = $.get("/people/"+id+".json");
gem js-routes
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"
✘
var promise, id;
id = 1; 
promise = $.get("/people/"+id+".json");
✔
var promise, id;
 
id = 1;
promise = $.get(Routes.person_path(id));
X
Exporte as traduções do
Rails para o JS
09
person.yml
pt-BR:
activerecord:
models:
person: Pessoa
people: Pessoas
attributes:
person:
id: ID
name: Nome
person.yml
pt-BR
✔
I18n.t(:person)
"Pessoa"
gem i18n-js
person.yml
pt-BR
✔
I18n.t(:person)
"Pessoa"
person.yml
pt-BR
✔
I18n.t(“activerecord.att
ributes.models.person”)
"Pessoa"
X
Faça o sprockets servir
templates JS usando ejs
10
✘var name, phone, html;
name = "The name";
phone = “(48) 1234-5678”;
 
html = "<p>Name:</p><p>" + name + "</p>";
html += "<p>Phone:</p><p>" + phone + “</p>”;
$("div#person").html(html)
gem ruby-ejs
// arquivo: application.js
 
//= require jquery
//= require jquery-ujs
//= require modulejs
//= require js-routes
//= require_tree ./templates
<p>Name:</p>
<p><%= name %></p>
 
<p>Phone:</p>
<p><%= phone %></p>
✘var name, phone, html;
name = "The name”;
phone = “(48) 1234-5678”;
 
html = "<p>Name:</p><p>" + name + "</p>";
html += "<p>Phone:</p><p>" + phone + “</p>”;
$("div#person").html(html)
var name, phone, html;
name = "The name”;
phone = “(48) 1234-5678”;
 
html = JST["templates/people/example"]({
name: name, phone: phone });
$("div#person").html(html)
✔
X
Crie escopos com IIFE11
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);
var foo = "value outside IIFE";
 
(function() {
var foo = "value inside IIFE";
console.log(foo);
}())
 
console.log(foo);
var foo = "value outside IIFE";
 
(function() {
var foo = "value inside IIFE";
console.log(foo);
}())
 
console.log(foo);
// Resultado:
// value inside IIFE
// value outside IIFE
Lembre-se que todos os seus
scripts acabarão em um
único arquivo
Sem escopo o resultado da
uglificação pode ser
imprevisível
X
Na boa… “use strict"12
Principal função: converter
enganos em erros!
(function () {
foo = "this should be a private content";
}())
✘
(function () {
foo = "this should be a private content";
}())
✘Falta do “use strict" fará
não gerar erro.
Falta do "var" fará de "foo" global
(function () {
"use strict";
foo = "this should be a private content";
}())
✘
(function () {
"use strict";
foo = "this should be a private content";
}())
✘ReferenceError: Can’t find variable foo
(function () {
"use strict";
var foo = "this should be a private content";
}())
✔
X
Fuja do callback hell
usando promises
13
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");
});
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");
});
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");
});
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");
});
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");
});
X
So long, and thanks for all the fish!
@cezinha_anjos
http://cezinha.info
http://asseinfo.com.br

Más contenido relacionado

La actualidad más candente

Desenvolvendo aplicações web com o framework cakephp
Desenvolvendo aplicações web com o framework cakephpDesenvolvendo aplicações web com o framework cakephp
Desenvolvendo aplicações web com o framework cakephpRodrigo Aramburu
 
Ambiente de Desenvolvimento Java usando Ant
Ambiente de Desenvolvimento Java usando AntAmbiente de Desenvolvimento Java usando Ant
Ambiente de Desenvolvimento Java usando AntDenis L Presciliano
 
CakePHP e o desenvolvimento rápido
CakePHP e o desenvolvimento rápidoCakePHP e o desenvolvimento rápido
CakePHP e o desenvolvimento rápidoIvan Rosolen
 
Criando serviços com AngularJS
Criando serviços com AngularJSCriando serviços com AngularJS
Criando serviços com AngularJSRodrigo Branas
 
Desenvolvimento de Módulos Divi Builder
Desenvolvimento de Módulos Divi BuilderDesenvolvimento de Módulos Divi Builder
Desenvolvimento de Módulos Divi BuilderDaniel Paz
 
Migrations for Java (Javou #4 - JavaCE)
Migrations for Java (Javou #4 - JavaCE)Migrations for Java (Javou #4 - JavaCE)
Migrations for Java (Javou #4 - JavaCE)Rafael Ponte
 
Interfaces ricas com Rails e React.JS @ Rubyconf 2015
Interfaces ricas com Rails e React.JS @ Rubyconf 2015Interfaces ricas com Rails e React.JS @ Rubyconf 2015
Interfaces ricas com Rails e React.JS @ Rubyconf 2015Rodrigo Urubatan
 
Construindo Sistemas Com Django
Construindo Sistemas Com DjangoConstruindo Sistemas Com Django
Construindo Sistemas Com DjangoMarinho Brandão
 
Node.js - #7 - Core Modules - http - Parte 1 - Rodrigo Branas
Node.js - #7 - Core Modules - http - Parte 1 - Rodrigo BranasNode.js - #7 - Core Modules - http - Parte 1 - Rodrigo Branas
Node.js - #7 - Core Modules - http - Parte 1 - Rodrigo BranasRodrigo Branas
 
TDC2015 Porto Alegre - Interfaces ricas com Rails e React.JS
TDC2015  Porto Alegre - Interfaces ricas com Rails e React.JSTDC2015  Porto Alegre - Interfaces ricas com Rails e React.JS
TDC2015 Porto Alegre - Interfaces ricas com Rails e React.JSRodrigo Urubatan
 
LambdaDay: Backbone.js
LambdaDay: Backbone.jsLambdaDay: Backbone.js
LambdaDay: Backbone.jsGiovanni Bassi
 
Jquery - Dicas e Truques
Jquery - Dicas e TruquesJquery - Dicas e Truques
Jquery - Dicas e TruquesLambda 3
 
AngularJS - 10 passos para aprender a criar suas directivas
AngularJS - 10 passos para aprender a criar suas directivasAngularJS - 10 passos para aprender a criar suas directivas
AngularJS - 10 passos para aprender a criar suas directivasJanderson Fernandes Cardoso
 
Introducao ao Spring Web MVC
Introducao ao Spring Web MVCIntroducao ao Spring Web MVC
Introducao ao Spring Web MVCEder Magalhães
 
Os 10 maus habitos dos desenvolvedores jsf (JustJava e CCT)
Os 10 maus habitos dos desenvolvedores jsf (JustJava e CCT)Os 10 maus habitos dos desenvolvedores jsf (JustJava e CCT)
Os 10 maus habitos dos desenvolvedores jsf (JustJava e CCT)Rafael Ponte
 

La actualidad más candente (20)

Spa com angular js flisol 2015 - aquidauana ms
Spa com angular js   flisol 2015 - aquidauana msSpa com angular js   flisol 2015 - aquidauana ms
Spa com angular js flisol 2015 - aquidauana ms
 
Desenvolvendo aplicações web com o framework cakephp
Desenvolvendo aplicações web com o framework cakephpDesenvolvendo aplicações web com o framework cakephp
Desenvolvendo aplicações web com o framework cakephp
 
Ambiente de Desenvolvimento Java usando Ant
Ambiente de Desenvolvimento Java usando AntAmbiente de Desenvolvimento Java usando Ant
Ambiente de Desenvolvimento Java usando Ant
 
Aula 07 acessibilidade
Aula 07  acessibilidadeAula 07  acessibilidade
Aula 07 acessibilidade
 
CakePHP e o desenvolvimento rápido
CakePHP e o desenvolvimento rápidoCakePHP e o desenvolvimento rápido
CakePHP e o desenvolvimento rápido
 
Criando serviços com AngularJS
Criando serviços com AngularJSCriando serviços com AngularJS
Criando serviços com AngularJS
 
Desenvolvimento de Módulos Divi Builder
Desenvolvimento de Módulos Divi BuilderDesenvolvimento de Módulos Divi Builder
Desenvolvimento de Módulos Divi Builder
 
Migrations for Java (Javou #4 - JavaCE)
Migrations for Java (Javou #4 - JavaCE)Migrations for Java (Javou #4 - JavaCE)
Migrations for Java (Javou #4 - JavaCE)
 
Rails na prática
Rails na práticaRails na prática
Rails na prática
 
Web Offline
Web OfflineWeb Offline
Web Offline
 
Interfaces ricas com Rails e React.JS @ Rubyconf 2015
Interfaces ricas com Rails e React.JS @ Rubyconf 2015Interfaces ricas com Rails e React.JS @ Rubyconf 2015
Interfaces ricas com Rails e React.JS @ Rubyconf 2015
 
Construindo Sistemas Com Django
Construindo Sistemas Com DjangoConstruindo Sistemas Com Django
Construindo Sistemas Com Django
 
Node.js - #7 - Core Modules - http - Parte 1 - Rodrigo Branas
Node.js - #7 - Core Modules - http - Parte 1 - Rodrigo BranasNode.js - #7 - Core Modules - http - Parte 1 - Rodrigo Branas
Node.js - #7 - Core Modules - http - Parte 1 - Rodrigo Branas
 
TDC2015 Porto Alegre - Interfaces ricas com Rails e React.JS
TDC2015  Porto Alegre - Interfaces ricas com Rails e React.JSTDC2015  Porto Alegre - Interfaces ricas com Rails e React.JS
TDC2015 Porto Alegre - Interfaces ricas com Rails e React.JS
 
LambdaDay: Backbone.js
LambdaDay: Backbone.jsLambdaDay: Backbone.js
LambdaDay: Backbone.js
 
Jquery - Dicas e Truques
Jquery - Dicas e TruquesJquery - Dicas e Truques
Jquery - Dicas e Truques
 
AngularJS - 10 passos para aprender a criar suas directivas
AngularJS - 10 passos para aprender a criar suas directivasAngularJS - 10 passos para aprender a criar suas directivas
AngularJS - 10 passos para aprender a criar suas directivas
 
Python 06
Python 06Python 06
Python 06
 
Introducao ao Spring Web MVC
Introducao ao Spring Web MVCIntroducao ao Spring Web MVC
Introducao ao Spring Web MVC
 
Os 10 maus habitos dos desenvolvedores jsf (JustJava e CCT)
Os 10 maus habitos dos desenvolvedores jsf (JustJava e CCT)Os 10 maus habitos dos desenvolvedores jsf (JustJava e CCT)
Os 10 maus habitos dos desenvolvedores jsf (JustJava e CCT)
 

Similar a RubyConfBr 2015 - Rails & Javascript: faça isso direito

Como Perder Peso (no browser)
Como Perder Peso (no browser)Como Perder Peso (no browser)
Como Perder Peso (no browser)Zeno Rocha
 
Mini-curso RubyOnRails CESOL
Mini-curso RubyOnRails CESOLMini-curso RubyOnRails CESOL
Mini-curso RubyOnRails CESOLtarginosilveira
 
JasperReports Tecnicas de geracao_de_relatorios1
JasperReports  Tecnicas de geracao_de_relatorios1JasperReports  Tecnicas de geracao_de_relatorios1
JasperReports Tecnicas de geracao_de_relatorios1Sliedesharessbarbosa
 
Offline Web com Service Workers - Sérgio Lopes
Offline Web com Service Workers - Sérgio LopesOffline Web com Service Workers - Sérgio Lopes
Offline Web com Service Workers - Sérgio LopesCaelum
 
Programando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkProgramando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkPablo Dall'Oglio
 
Desenvolvendo com Dojo Toolkit
Desenvolvendo com Dojo ToolkitDesenvolvendo com Dojo Toolkit
Desenvolvendo com Dojo ToolkitFlávio Lisboa
 
Apresentação CEJS - Do nada para a nuvem
Apresentação CEJS - Do nada para a nuvemApresentação CEJS - Do nada para a nuvem
Apresentação CEJS - Do nada para a nuvemRodrigo Valerio
 
J query apostila - noções básicas
J query   apostila - noções básicasJ query   apostila - noções básicas
J query apostila - noções básicasLuciano Marwell
 
JQuery - introdução ao
JQuery - introdução ao JQuery - introdução ao
JQuery - introdução ao Daniel Filho
 
Iniciando com Yii Framework - Volmar Machado da Silva Neto (Rede Pampa de Com...
Iniciando com Yii Framework - Volmar Machado da Silva Neto (Rede Pampa de Com...Iniciando com Yii Framework - Volmar Machado da Silva Neto (Rede Pampa de Com...
Iniciando com Yii Framework - Volmar Machado da Silva Neto (Rede Pampa de Com...Tchelinux
 
JavaScript e JQuery para Webdesigners
JavaScript e JQuery para WebdesignersJavaScript e JQuery para Webdesigners
JavaScript e JQuery para WebdesignersHarlley Oliveira
 
Desenvolvendo aplicacoes mobile_com_html_css_
Desenvolvendo aplicacoes mobile_com_html_css_Desenvolvendo aplicacoes mobile_com_html_css_
Desenvolvendo aplicacoes mobile_com_html_css_Rodrigo Urubatan
 
Workshop Node.js + MongoDB + Mongoose
Workshop Node.js + MongoDB + MongooseWorkshop Node.js + MongoDB + Mongoose
Workshop Node.js + MongoDB + MongooseLuiz Duarte
 
Testando Rails apps com RSpec
Testando Rails apps com RSpecTestando Rails apps com RSpec
Testando Rails apps com RSpecNando Vieira
 
Melhorando a Experiência do Usuário com JavaScript e jQuery
Melhorando a Experiência do Usuário com JavaScript e jQueryMelhorando a Experiência do Usuário com JavaScript e jQuery
Melhorando a Experiência do Usuário com JavaScript e jQueryHarlley Oliveira
 
Python e Django
Python e DjangoPython e Django
Python e Djangopugpe
 
Minicurso de JavaScript (Portuguese)
Minicurso de JavaScript (Portuguese)Minicurso de JavaScript (Portuguese)
Minicurso de JavaScript (Portuguese)Bruno Grange
 

Similar a RubyConfBr 2015 - Rails & Javascript: faça isso direito (20)

Como Perder Peso (no browser)
Como Perder Peso (no browser)Como Perder Peso (no browser)
Como Perder Peso (no browser)
 
Mini-curso RubyOnRails CESOL
Mini-curso RubyOnRails CESOLMini-curso RubyOnRails CESOL
Mini-curso RubyOnRails CESOL
 
JasperReports Tecnicas de geracao_de_relatorios1
JasperReports  Tecnicas de geracao_de_relatorios1JasperReports  Tecnicas de geracao_de_relatorios1
JasperReports Tecnicas de geracao_de_relatorios1
 
Offline Web com Service Workers - Sérgio Lopes
Offline Web com Service Workers - Sérgio LopesOffline Web com Service Workers - Sérgio Lopes
Offline Web com Service Workers - Sérgio Lopes
 
Programando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkProgramando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um Framework
 
Zend Framework
Zend FrameworkZend Framework
Zend Framework
 
Desenvolvendo com Dojo Toolkit
Desenvolvendo com Dojo ToolkitDesenvolvendo com Dojo Toolkit
Desenvolvendo com Dojo Toolkit
 
Apresentação CEJS - Do nada para a nuvem
Apresentação CEJS - Do nada para a nuvemApresentação CEJS - Do nada para a nuvem
Apresentação CEJS - Do nada para a nuvem
 
J query apostila - noções básicas
J query   apostila - noções básicasJ query   apostila - noções básicas
J query apostila - noções básicas
 
JQuery - introdução ao
JQuery - introdução ao JQuery - introdução ao
JQuery - introdução ao
 
J query basico
J query basicoJ query basico
J query basico
 
Iniciando com Yii Framework - Volmar Machado da Silva Neto (Rede Pampa de Com...
Iniciando com Yii Framework - Volmar Machado da Silva Neto (Rede Pampa de Com...Iniciando com Yii Framework - Volmar Machado da Silva Neto (Rede Pampa de Com...
Iniciando com Yii Framework - Volmar Machado da Silva Neto (Rede Pampa de Com...
 
JavaScript e JQuery para Webdesigners
JavaScript e JQuery para WebdesignersJavaScript e JQuery para Webdesigners
JavaScript e JQuery para Webdesigners
 
Desenvolvendo aplicacoes mobile_com_html_css_
Desenvolvendo aplicacoes mobile_com_html_css_Desenvolvendo aplicacoes mobile_com_html_css_
Desenvolvendo aplicacoes mobile_com_html_css_
 
Workshop Node.js + MongoDB + Mongoose
Workshop Node.js + MongoDB + MongooseWorkshop Node.js + MongoDB + Mongoose
Workshop Node.js + MongoDB + Mongoose
 
Testando Rails apps com RSpec
Testando Rails apps com RSpecTestando Rails apps com RSpec
Testando Rails apps com RSpec
 
Melhorando a Experiência do Usuário com JavaScript e jQuery
Melhorando a Experiência do Usuário com JavaScript e jQueryMelhorando a Experiência do Usuário com JavaScript e jQuery
Melhorando a Experiência do Usuário com JavaScript e jQuery
 
Python e Django
Python e DjangoPython e Django
Python e Django
 
Minicurso de JavaScript (Portuguese)
Minicurso de JavaScript (Portuguese)Minicurso de JavaScript (Portuguese)
Minicurso de JavaScript (Portuguese)
 
Grails
GrailsGrails
Grails
 

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