MadResponse
Response builder fluente com 30+ ops parciais.
Mad\Http\MadResponse é o builder fluente de respostas parciais do MadWire — toda
action de MadComponent que precisa atualizar a UI sem um full re-render retorna
(ou envia) uma instância dele. Cada método adiciona uma op (uma instrução
serializável) à lista interna $ops, que o JavaScript do client aplica em
sequência via Mad.applyOps().
Esta página cobre construção, encadeamento e o ciclo de vida da classe. Para a lista exaustiva de métodos (manipulação de DOM, toasts, navegação, kanban, gantt, tree-view, detail-form, recarregar combos/checklists...), ver MadResponse — todas as ops.
Construção e encadeamento
Toda op retorna $this (tipo static) — encadeável livremente:
use Mad\Http\MadResponse;
return new MadResponse(); // sem ops — dispara re-render total do componente
return (new MadResponse())
->toast('Salvo!', 'success')
->closeDrawer();
public function onAprovar(int $id): MadResponse
{
Pedido::find($id)->update(['status' => 'aprovado']);
return (new MadResponse())
->toast('Aprovado!', 'success')
->html('#status-badge', '<span class="mad-badge mad-badge-success">Aprovado</span>')
->closeDrawer()
->manageRow($id, PedidoListagem::class);
}
void vs MadResponse
Quando uma action só muda state (props públicas, $form->set()),
retorne void — o framework calcula o diff e gera as ops (val,
bind, reload_*) automaticamente. Reserve MadResponse
explícito para UX que o diff de state não cobre: toast, fechar modal/drawer, navegar,
manipular DOM fora do form.
// void — só muda state. O handler faz o diff e gera val/bind/reload_* sozinho.
public function onTipoChange(string $tipo): void
{
$this->form->set('descricao', TipoProduto::find($tipo)->descricao);
}
// MadResponse — quando você precisa de UX explícito (toast, fechar, navegar)
public function onSave(): MadResponse
{
$produto = Produto::findOrNew($this->registroId);
$this->form->save($produto);
return (new MadResponse())
->toast('Salvo!', 'success')
->closeDrawer();
}
Ver Auto-bind para como o diff funciona por dentro.
Ops parciais vs full re-render
Sem nenhuma op (new MadResponse() "vazio"), o componente sofre
re-render total: o state é serializado, view() é chamado de
novo, e o DOM inteiro do wrapper é substituído. Cada op específica
(html, val, manageRow...) é parcial —
atualiza só o alvo necessário.
Prefira manageRow()/manageCard() para atualizar/inserir uma
linha específica, ou html('#regiao', ...) para uma área isolada — ver
Render parcial.
Atalhos estáticos
use Mad\Http\MadResponse;
// Atalhos estáticos — criam, preenchem e ENVIAM (encerram a execução)
MadResponse::ok('Operação realizada com sucesso!'); // toast success + send()
MadResponse::err('Falha ao processar.'); // toast danger + send()
// Abre um MadComponent detectando o wrapper sozinho (igual MadAction::auto())
return MadResponse::open('DocProdutoForm', ['id' => $id]);
return MadResponse::open('DocProdutoForm', ['id' => $id], 'onEdit'); // método custom
| Método estático | Comportamento |
|---|---|
ok($message = '...') | Cria, adiciona toast success e já chama send() — não retorna. |
err($message) | Mesma ideia, toast danger. |
open($class, $params = [], $method = 'show') | Abre um MadComponent com auto-detect de wrapper (delega para MadAction). |
send() vs getOps() vs merge()
A maioria das actions de MadComponent apenas return o
MadResponse — o MadComponentHandler chama getOps()
internamente e serializa a resposta. send() é para o caso explícito de métodos
estáticos chamados direto pelo client (lookups, field actions via
fetch) — nesse contexto não há um retorno tipado pro handler interceptar, então
o método precisa imprimir o JSON e encerrar a execução sozinho:
// Métodos estáticos chamados pelo client (field actions, lookups via fetch) —
// não retornam: encerram a request com send().
public static function onExitCep(): void
{
$cep = preg_replace('/\D/', '', $_POST['cep'] ?? '');
$data = json_decode(file_get_contents("https://viacep.com.br/ws/{$cep}/json/"), true);
(new MadResponse)
->val('#logradouro', $data['logradouro'])
->val('#bairro', $data['bairro'])
->val('#cidade', $data['localidade'])
->val('#uf', $data['uf'])
->toast('CEP preenchido!', 'success')
->send();
}
| Método | Retorno | Uso |
|---|---|---|
getOps() | array | Array de ops, sem enviar nem encerrar — usado internamente pelo MadComponentHandler. |
merge(MadResponse $other) | static | Concatena as ops de outro MadResponse neste (útil ao compor respostas de helpers como MadToast/MadValidationException). |
send() | never | Manda Content-Type: application/json, echo do JSON + exit — só em métodos estáticos chamados direto via AJAX. |
emit() | void | echo de um <script> inline que chama Mad.applyOps(...) — só para dispatch clássico (página/janela cujo retorno NÃO é serializado pelo wire), ex.: redirect('LoginForm')->emit() pós-logout. |
emit()
emit() devolve HTML (<script>), não JSON —
quem consome a resposta com Mad.applyOps(await res.json()) quebra. Um método
public static chamado por fetch/Mad.exec deve
terminar em send(), ou fazer o echo json_encode($resp->getOps())
explicitamente. emit() serve apenas quando o navegador está carregando a
saída como documento.
getOps() e send() ainda anexam os dumps pendentes de
mad_dump_modal()/mdm() via MadDumpModal::inject(). Se
houver payload de debug ativo (MadLogService), send() troca o corpo
de array-de-ops puro para { "ops": [...], "_debug": {...} }.