Skip to content

Allow implementing signal form value transformations without a custom component #70197

Description

@robmv

Which @angular/* package(s) are relevant/related to the feature request?

forms

Description

Currently FormValueControl and transformedValue can only be implemented in a component, and FormValueControl is tied to the core render code packages/core/src/render3/instructions/control.ts, It is a flag added to a node. If I understand correctly. It is static.

The old ControlValueAccessor could be replaced by a new one using injection. This does not look possible with FormValueControl. My personal use case is that I have directives that allow form controls in reactive forms tied to a plaininput element to parse the content and put parsed values on the model, like numbers, @js-joda's LocalDate, bignumber.js BigNumber, etc.. All this without creating custom components wrapping an input, putting a directive directly on the input.

Proposed solution

The general problem of overriding the default FormValueControl Angular already provides for input, textarea, etc. with a custom one, could be solved possibly with Injection.

My specific problem of transforming values without the need to create a custom control and all the issues in the alternatives below, Maybe allow us to use a variation of transformedValue in the schema function, without a custom component.

Alternatives considered

There are two alternatives.

Use a wrapper component with an internal input. This works, and all examples show exactly this. What this breaks, The input is hidden to the parent view., It is not possible to style it directly, you will need to use global styles instead of component attached styles, or expose all the styles that you will ever need maybe with CSS variables.

<my-parsed-input [formField]="..."/>

Another alternative is still a wrapper component, but instead of embedding the input inside the component view, use content projection to bring a literal input that is inside the component content. This way the view is completly aware iof the input and can be locally styled.

<my-parsed-input [formField]="...".>
  <input class="myInputStyle"/>
</my-parsed-input>

This is more flexible tor styling the input, but is error prone, [formField] could be places by accident in the input instead of of the top component, It is extremely verbose.

This becomes a large implementation because now my-parsed-input need to pass all metadata that is attached for validators like maxLength from my-parsed-input to the internal input.

Do not even talk about using MatFormField int the first alternative, It will force to implement MatFormFieldControl in the component adding matInput to the inner input will do nothing because it is another view, MatFormField will not see that

The third and worse alternative IMHO is to have strings in the model, all validations that require the model to be more than strings need to reparse the values each time inside the valdiator, for example to validate a LocalDate, parse the string in the validator, then use the LocalDate methods

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status
    No status

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions