Multiplicador: Componentes dinâmicos
Uma ferramenta para a criação dinâmica de componentes interativos
Vamos começar com um problema típico: temos uma lista de produtos em um site de comércio eletrônico e queremos acompanhar cada produto com um formulário add to cart. Uma das maneiras é envolver toda a lista em um único formulário. Uma maneira mais conveniente é usar Nette\Application\UI\Multiplier.
O multiplicador permite definir uma fábrica para múltiplos componentes. Ele se baseia no princípio de componentes aninhados – cada componente herdado de Nette\ComponentModel\Container pode conter outros componentes.
Veja o modelo dos componentes na documentação.
O multiplicador posa como um componente pai que pode criar dinamicamente seus filhos usando a callback passada no construtor. Veja o exemplo:
No modelo podemos apresentar um formulário para cada produto – e cada formulário será de fato um componente único.
Argumento passado para {control}
tag diz:
- obter um componente
shopForm
- e devolver seu filho
$item->id
Durante a primeira chamada de 1. o componente shopForm
ainda não existe, portanto o método
createComponentShopForm
é chamado para criá-lo. Uma função anônima passada como parâmetro para
o Multiplicador, é então chamada e um formulário é criado.
Nas iterações subsequentes do foreach
o método createComponentShopForm
não é mais chamado
porque o componente já existe. Mas como fazemos referência a outra criança ($item->id
varia entre
iterações), uma função anônima é chamada novamente e uma nova forma é criada.
A última coisa é garantir que o formulário realmente acrescente o produto correto ao carrinho porque no estado atual
todos os formulários são iguais e não podemos distinguir a que produtos eles pertencem. Para isso, podemos usar a propriedade
de Multiplicador (e em geral de qualquer método de fábrica de componentes em Nette Framework) que cada método de fábrica de
componentes recebe o nome do componente criado como o primeiro argumento. Em nosso caso, isso seria $item->id
,
que é exatamente o que precisamos para distinguir os produtos individuais. Tudo o que precisamos fazer é modificar o código
para criar o formulário: