Consulta la API del componente para elegir el binding. Un nombre terminado en Change no siempre representa un modelo. Esta tabla describe las seis responsabilidades con ejemplos reales de Neural.
Contrato
Quién gobierna el estado
¿Puede el componente aplicar un valor?
Qué recibe la aplicación
Ejemplo Neural
A · INPUT
Aplicación
No: lee el valor que recibe.
Nada automáticamente.
Button.disabled
B · MODEL
Valor editable compartido
Sí, mediante el modelo documentado.
El valor actualizado.
Input.value / valueChange
C · PROPOSAL
Aplicación
No: la aplicación acepta o rechaza.
Una solicitud, no un resultado aplicado.
Dialog.open / closeRequested
D · DOMAIN EVENT
La aplicación decide la consecuencia.
No implica actualizar un estado.
Interacción y payload.
Button.neuClick: MouseEvent
E · LIFECYCLE
El ciclo de vida observado
No es un valor editable.
Notificación tras la transición documentada.
Dialog.opened / closed
F · INTERNAL DERIVED
Implementación del componente
Deriva el comportamiento del estado público.
Ningún binding público adicional.
Button bloquea la activación con disabled o loading.
La aplicación proporciona Button.disabled. Cambiar su signal decide si el botón puede activarse; Button no devuelve un nuevo valor de disabled. Este ejemplo es síncrono y solo enseña quién gobierna un input.
example.ts
import { Component, signal } from '@angular/core';
import { NeuButtonComponent } from '@neural-ui/core/button';
import { NeuSwitchComponent } from '@neural-ui/core/switch';
@Component({
selector: 'app-input-example',
imports: [NeuButtonComponent, NeuSwitchComponent],
template: `
<neu-switch
label="Block action"
[(checked)]="blocked"
/>
<button
neu-button
type="button"
[disabled]="blocked()"
(neuClick)="count.update(increment)"
>
Run
</button>
<output aria-live="polite">{{ count() }}</output>
`,
})
export class InputExample {
readonly blocked = signal(false);
readonly count = signal(0);
readonly increment = (value: number) => value + 1;
}
Input emite valueChange después de editar. El handler actualiza el mismo signal que proporciona value. Restablecer cambia ese signal desde la aplicación; no hay otro valor local. [(value)]="name" es la forma bidireccional equivalente: elige una forma de binding para cada control.
Abre Dialog y pulsa Escape. Si la aceptación está activada, el handler cambia open a false. Si está desactivada, se emite closeRequested, pero open sigue en true. Terminar y cerrar ejecuta una acción explícita de aplicación. Core devuelve el foco cuando el diálogo se cierra de verdad.
No utilices [(open)] aquí: Dialog expone un input y una solicitud, no un modelo open.
Button.neuClick comunica una activación con un MouseEvent. La aplicación decide la consecuencia. En el primer componente aumenta un contador; también podría abrir una tarea o iniciar una operación.
opened y closed del ejemplo Dialog observan las transiciones del estado open aplicado. No solicitan un cambio y no deben convertirse en otro binding de open. Los contadores empiezan en cero: Core no emite ese ciclo de vida durante el primer render.
Button deriva el bloqueo de activación de disabled y loading. Configura esos inputs públicos; no enlaces helpers internos ni reproduzcas manualmente su semántica deshabilitada.