Talvez você tenha se perguntado a existência da gem stimulus
que Rails instala por padrão, mas não se preocupe, que aqui você vai aprender sobre ele.
Observação: Esse post é necessário que tenha um conhecimento DOM. Se não, pode ser complicado em entender.
O que é Stimulus?
Eu vou traduzir a documentação, pois, sinceramente, não consigo explicar isso em outras palavras.
Stimulus é um framework Javascript com ambições modesta.
Ao contrário de outros frameworks front-end, Stimulus é projetado para aprimorar HTML estático ou renderizado pelo servidor - o "HTML que você possui" - conectando objetos Javascript a elementos da página usando anotações simples.
Esses objetos JavaScript são chamados de controllers, e o Stimulus monitora continuamente a página esperando que os atributos data-controller
apareçam no HTML. Para cada atributo, o Stimulus examina o valor do atributo para encontrar uma classe controller correspondente, cria uma nova instância dessa classe e a conecta ao elemento.
Você pode pensar desta maneira: Assim como o atributo class
é uma ponte que conecta HTML a CSS, o atributo data-controller
do Stimulus é uma ponte que conecta HTML a Javascript
Além dos controllers, os outros três principais conceitos de Stimulus são:
-
actions
, que conectam métodos do controller a eventos DOM usando atributosdata-action
; -
targets
, que localizam elementos de significado dentro de um controller; -
values
, que leem, escrevem e observam atributos de dados no elemento do controller.
O uso de atributos de dados pelo Stimulus ajuda a separar o conteúdo do comportamento da mesma forma que o CSS separa o conteúdo da apresentação. Além disso, as convenções do Stimulus naturalmente encorajam você a agrupar códigos relacionados por nome.
Por sua vez, o Stimulus ajuda você a criar controllers pequenos e reutilizáveis, fornecendo estrutura suficiente para evitar que seu código se transforme em uma “sopa de JavaScript”.
Talvez, com essa explicação, você não tenha entendido muito, então vamos para a prática para fixar isso.
Prática
Eu estava pensando que tipo de aplicação eu criaria para isso, porém, não consegui em pensar em nada. Então vai ser uma aplicação aleatória que possa aproveitar o máximo do Stimulus.
Então, execute os comandos abaixo para preparar o terreno.
rails new exemplo_stimulus
cd exemplo_stimulus
rails g controller Pagina index
Abra o arquivo config/routes.rb
.
# config/routes.rb
Rails.application.routes.draw do
root 'pagina#index'
end
Agora, o nosso terreno está pronto.
Controllers
Vá no arquivo app/views/pagina/index.html.erb
e adicione o código abaixo.
<!-- app/views/pagina/index.html.erb -->
<div data-controller="hello"></div>
Rode o servidor e vá para URL localhost:3000
e veja a mágica acontecer.
Viu, apareceu o "Hello world!", mas como?
Antes de explicar, o que aconteceu, vamos, primeiro, entender sobre o atributo data-controller
.
Como foi explicado lá em cima, que o Stimulus procura no html pelo o atributo data-controller
para criar uma instância de classe e conectar com o elemento.
Só que a dúvida é, onde está essa classe?
Bem, na sua aplicação, procure o arquivo no diretório app/javascript/controllers
e verá ele lá.
Achou? E qual é o nome do arquivo?
hello_controller.js
é o nome do arquivo, ou seja, o Stimulus vai usar o valor do atributo para procurar um arquivo do diretório app/javascript/controllers
.
Vamos fazer um teste, mude o valor do data-controller
.
<!-- app/views/pagina/index.html.erb -->
<div data-controller="ola"></div>
Agora, reinicie a página e verá ...
Nada, obviamente, esperava o que?
Bem, por que não apereceu nada?
É que Stimulus está procurando um arquivo com nome ola_controller.js
e esse arquivo não existe.
Então, vamos mudar o nome do arquivo hello_controller.js
para ola_controller.js
e reinicie a página.
Agora, funcionou.
Uma observação, é necessário que tenha o nome _controller.js
no final do arquivo.
Bem, eu acho que você sacou como que funciona o data-controller
.
Agora, vamos abrir o app/javascript/controllers/ola_controller
e observar ele.
// app/javascript/controllers/ola_controller
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
connect() {
this.element.textContent = "Hello World!"
}
}
Não tem muito segredo nesse arquivo, então eu vou só explicar o método connect
, pois o resto dá para entender de boa.
O método connect
é executado, quando usar o atributo data-controller
.
Beleza, agora vamos nos aprofundar um pouco.
Actions
Vá para o arquivo app/views/pagina/index.html.erb
e coloque o código abaixo.
<!-- app/views/pagina/index.html.erb -->
<div data-controller="ola">
<input type="text" data-action="keyup->ola#mudarTexto">
<p></p>
</div>
Ok, nós temos um novo atributo.
O data-action
serve para lida com evento DOM do seu controller.
Vamos observar o valor do nosso atributo data-action
.
Observando ele, você pode notar um padrão, que é, começa com evento DOM keyup
e vai para o controller ola
e execute o método mudarTexto
.
Ou seja, é desse jeito o padrão evento->controller#método
.
Não tem muito mistério sobre isso, basta lembrar desse padrão.
Então vamos para o arquivo app/javascript/controllers/ola_controller.js
e colocar o novo método e remover o connect
.
// app/javascript/controllers/ola_controller.js
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
mudarTexto(event) {
console.log(event.target.value);
}
}
Pronto, reinicie a página e abra o dev tools para ver o console.
Viu, ele está imprimindo o valor do input.
Você pode pensar, nossa, que simples.
Sim, de fato, é muito simples.
Agora vamos mergulhar mais, que já estamos quase no fim.
Targets
Novamente, edite o arquivo, app/views/pagina/index.html.erb
.
<!-- app/views/pagina/index.html.erb -->
<div data-controller="ola">
<input type="text" data-action="keyup->ola#mudarTexto">
<p data-ola-target="texto"></p>
</div>
Hum, um outro atributo.
Esse atributo é bem diferente, se prestar atenção, você pode ver o nome do controller no meio, ou seja, para usar ele, tem que seguir esse padrão, data-nome_do_controller-target
.
Mas a questão é, o que ele faz?
Como o nome diz, ele é um alvo do controller.
O uso dele seria equivalente a GetElementById
, só que mais simples.
Vamos para o arquivo app/javascript/controllers/ola_controller.js
.
// app/javascript/controllers/ola_controller.js
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = [ "texto" ]
mudarTexto(event) {
this.textoTarget.textContent = `olá, ${event.target.value}`
}
}
Pode notar que existe uma variável targets
, em que, está atribuindo um array com um valor "texto"
, ou seja, tem ter o valor igual, onde foi posto no HTML.
Agora, se você observar o this.textoTarget
, ele é o elemento, a qual você colocou o atributo data-ola-target
.
Então reinicie a página, e veja a mágica acontecer.
Values
O último conceito do Stimulus, então, abra o arquivo index novamente.
<!-- app/views/pagina/index.html.erb -->
<div data-controller="ola" data-ola-nome-value="Zulano" >
<input type="text" data-action="keyup->ola#mudarTexto">
<p data-ola-target="texto"></p>
</div>
Beleza, antes de explicar esse atributo, vamos primeiro para o arquivo javascript.
// app/javascript/controllers/ola_controller.js.
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = [ "texto" ]
static values = {
nome: String
}
mudarTexto(event) {
console.log(this.nomeValue)
this.textoTarget.textContent = `olá, ${event.target.value}`
}
}
Pode notar que ele meio que equivalente ao target, o que muda é que o targets aceita um array, enquanto o values é um JSON.
O padrão do atributo é data-nome_do_controller-chave-value
.
Novamente, reinicie a página e veja o console do dev tools.
Bem, eu vou acabar por aqui, isso é o básico do Stimulus.
Eu sinto que esse post foi um desastre, mas se houver qualquer dúvida, pode comentar que vou responder.
Bem, então é isso, tchau!
Top comments (2)
Valeu, Alexandre. Artigo muito bom e esclarecedor.
Show Alexandre, simples e direto!