Closed WhitWaldo closed 3 years ago
Thanks for contacting us.
Why are you trying to use InputText
and not the HTML input
element instead then?
InputText etc are html inputs wrapped in a component that will additionally update state in an EditContext (Is the value modified or invalid).
If you don't want your input UI to talk to the EditContext then skip the Input* components and just do <input @bind=whatever/>
instead.
@mkArtakMSFT @mrpmorris I completely missed this in the documentation, but I do understand this now.
Nothing to do here then. Thank you for your feedback and responses!
Is your feature request related to a problem? Please describe.
Today, one cannot bind to the value of a
TextInput
or other input fields without putting them inside of anEditForm
. One cannot set up anEditForm
that doesn't either specify aModel
or anEditContext
for validation (which in turn requires the model).I've got an elaborate form that accepts some strings, then optionally attaches a number of complex models if the user opts into using them. I previously set this up using this prescribed approach - a model that contains all the various required and simple properties with nullable properties for the optional fields to satisfy the EditForm requirement. Because my @code block was getting quite long and unwieldy, and because each of the optional models required a remote lookup, I took each and put them into a separate component so that lookup would only be done if the component was rendered. This cleaned up the @code block for each piece considerably, and then I just used parameterized EventCallbacks to pass the state of the component back to the parent upon successfully filling the pieces out.
But this introduced an awful lot of ceremony in the code. The parent component containing the form had to have EventCallback methods for each of these optional pieces to update the form's model out of band and each of the optional pieces had to have input parameters so I could pass in current values from the parent. It was less of a mess than putting it all on one component, but still pretty ugly.
So I got to thinking and found this blog post that speaks to three ways of communicating across Blazor components. The last approach stood out to me as optimal: Introduce one class that represents a singleton state of the data across all these form elements. Each component can just read what it needs out of there, set what it needs to via methods on the class. Each component, instead of binding to a local model can instead have each component bind to a string property in which the setter updates the global model.
This allows me to opt out of the outbound
EventCallbacks
between all the components, lets me drop the inbound[Parameters]
and really only requires that I have an@inject MyState state
at the top of each form component.As example, this then looks like the following:
A peek inside one of these components (they're all similar) looks like the following, to use SubComponentA here:
This would be amazing except.. it doesn't work. It fails at runtime with an error that reads "System.InvalidOperationException: EditForm requires either a Model parameter, or an EditContext parameter, please provide one of these."
A clear and concise description of what the problem is.
EditForm requires that a
Model
orEditContext
be specified in order to use it. It's impossible to use any of the Input elements (e.g.InputText
) without using an EditForm and this approach doesn't lend to more complex forms that use a global state like my approach here.Describe the solution you'd like
Rather, I'd like to see a way to opt-out of the model binding altogether (e.g. just don't specify either a Model or an EditContext), but still let me use the @bind-Value and event handling capabilities on the input elements to manually handle the value of each control in the form.