Múltiplos controllers, um elemento

Prévia grátis 3 min de leitura

O data-controller não se limita a um identificador. Escreva dois, separados por espaço, e os dois controllers se conectam ao mesmo elemento de forma independente, cada um com seus próprios targets, values e ciclo de vida. Nenhum sabe que o outro existe, a menos que algo os conecte explicitamente. A UI de desafio real desta aplicação, o editor Ruby da aula de desafio deste próprio curso, faz isso.

Dois controllers reais compartilhando um elemento

A tag de abertura do bloco de desafio em app/views/catalog/lessons/show.html.erb:

<div class="mt-16 pt-12 border-t border-subtle"
     data-controller="execution--irb execution--hints"
     data-action="execution--irb:failed->execution--hints#attemptFailed"
     data-execution--irb-challenge-id-value="<%= @challenge.id %>"
     data-execution--hints-url-value="<%= execution_api_v1_challenge_solution_path(@challenge) %>"
     data-execution--hints-failed-attempts-value="<%= @failed_attempts %>"
     data-execution--hints-required-attempts-value="<%= Execution::SolutionAccessPolicy::REQUIRED_FAILED_ATTEMPTS %>"
     data-execution--hints-revealed-value="<%= @solution_revealed %>">

Essa linha data-action é a ligação entre os dois controllers. Como ela funciona é assunto da aula 4. Por ora, note só que ela é real, está nesse mesmo elemento, e nenhum dos dois controllers precisou ser avisado dela. Um <div> leva dois identificadores de controller no data-controller: execution--irb e execution--hints. O Stimulus instancia os dois sobre este mesmo elemento. O execution--irb ganha seu próprio this.element (essa div), e o execution--hints também: o mesmo nó do DOM, duas instâncias de controller separadas, sem relação entre si por padrão.

Cada controller lê só os próprios values

Os atributos de value têm o prefixo de cada controller: data-execution--irb-challenge-id-value pertence ao execution--irb, e data-execution--hints-failed-attempts-value pertence ao execution--hints. O curso "StimulusJS: values/classes" mostrou como o nome do atributo HTML de um value vem do identificador do seu controller. É por isso que dois controllers podem dividir um elemento sem que seus values colidam. O value challengeId do execution--irb e o value url do execution--hints ficam em atributos com prefixos diferentes na mesma tag, e cada controller ignora as declarações do outro.

Por que colocá-los no mesmo elemento

O execution--irb roda o código do estudante no navegador, em ruby.wasm, como prévia, e depois o envia. A nota vem do servidor, e é por esse veredito que o controller sabe se a tentativa passou ou falhou. O execution--hints cuida da revelação de dicas e da trava da solução, a mecânica de "dicas liberadas após tentativas falhas" que um estudante vê na aula de desafio deste próprio curso. São duas responsabilidades separadas, e dividi-las em dois controllers deixa cada um pequeno. O execution--irb nunca mexe no DOM das dicas, e o execution--hints nunca roda nem envia código. Dividir um elemento é o que torna possível o mecanismo da aula 4. Um evento disparado a partir do this.element de um controller alcança qualquer coisa que escute nesse mesmo elemento, então não é preciso um broadcast global quando os dois controllers vivem no mesmo nó.

Pontos-chave

  • O data-controller aceita vários identificadores separados por espaço; cada um ganha sua própria instância de controller, independente, conectada ao mesmo elemento.
  • A UI de desafio real desta aplicação (show.html.erb) conecta execution--irb e execution--hints ao mesmo <div>, o elemento por trás do desafio deste próprio curso.
  • Os atributos de static values de cada controller continuam com o prefixo do próprio identificador, então dois controllers num elemento nunca colidem nos nomes de atributo.
  • Separar o execution--irb (roda o código) do execution--hints (UI de dicas e solução) mantém estreita a responsabilidade de cada controller, mesmo com os dois agindo sobre um elemento compartilhado.
Aula 1 de 7 · grátis

Continue com a aula 2

this.dispatch(): os próprios eventos customizados de um controller

Como o método herdado dispatch() dispara eventos customizados, com defaults para alvo, detail, propagação e prefixo.

Com uma conta grátis você também tem os quizzes, seu progresso e suas anotações, e a discussão.

Digite para buscar...