-
Notifications
You must be signed in to change notification settings - Fork 27.2k
Description
Which @angular/* package(s) are relevant/related to the feature request?
No response
Description
The documentation of signal forms highlights the common use case of Value Transformation.
It suggests using a computed signal to transform the input value into its display representation.
The current FormValueControl interface only supports the value as a ModelSignal, so the computation will be re-run on every value change triggered by the user, which leads to very strange input behavior.
I don't believe that it is possible to do this kind of transformation without separating the model signal into an input and output signal, as setting the model value will always inevitably lead to a recomputation of the display value.
Proposed solution
Supporting separated input and output signal implentation of FormValueControl would allow a solution like this:
@Component({
selector: 'app-currency-input',
imports: [],
templateUrl: './currency-input.html',
styleUrl: './currency-input.scss',
})
export class CurrencyInput implements FormValueControl<number> {
valueInput = input<number>(0);
valueChange = output<number>();
displayValue = linkedSignal(() => this.convertToDisplayValue(this.valueInput()));
private value = linkedSignal(() => this.valueInput());
handleInput(input: string) {
this.displayValue.set(input);
const num = parseFloat(input.replace(/[^0-9.]/g, ''));
if (isNaN(num)) return;
this.value.set(num);
this.valueChange.emit(num);
}
onBlur() {
this.displayValue.set(this.convertToDisplayValue(this.value()));
}
private convertToDisplayValue(value: number) {
return value.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
}Alternatives considered
One could put the value.set() call intoonBlur() but then the field value will not be continuously updated.
Metadata
Metadata
Assignees
Type
Projects
Status