-
Notifications
You must be signed in to change notification settings - Fork 25.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
I'd like to be able to use ngModel without specifying a name #9230
Comments
We considered this. The problem is that your forms will no longer behave predictably. In the example above, what would form.value be? There's no way to refer to the input you've added, so it would have to be An alternative might be to have the form avoid registering any ngModels without names, but that seems more confusing. Some inputs simply wouldn't appear in the aggregate form value. (It's worth noting that outside of a form tag, you can use ngModel without a name.) I'd love to hear some more opinions on this. Thoughts? |
https://plnkr.co/edit/CcXGHjI6jkkW8YpR28ZI?p=preview I think this is a valid case, specially when I don't want to have the form.value to contain the value specified by [(ngModel)]. I have at least two forms which relied on this to work. But with new form it no longer works. ngModel works outside of a form without a name, but then I had to rearrange the controls in form just so that, the controls are in form and ngModel without name outside of form. But it does not look good to me. |
How should we deal with dynamically added inputs then? Currently, |
@vsavkin let me know that there may currently be an issue with submit events that made my use case fail in the first place. I was also missing In the new forms paradigm, for me to not use the new forms capabilities automatically, I can either not use a |
@wrldtrvllr that's the exact case I'm dealing with. My dynamic form element (which renders a specific custom form element based on meta data from the API) breaks now in RC2 because it doesn't have a name, nor does it need one. In fact, in that case, name makes absolutely no sense. |
I can not use any custom-made form elements any more. For example, I am using a WYSIWYG-Editor in my forms:
Without the name I get this error: " Name attribute must be set if ngModel ..." . With the name set : "ORIGINAL EXCEPTION: No value accessor for 'description'" . I get the same for a custom-made DatePicker-Component. The "new forms" are, like we call it in Germany, a classic "Verschlimmbesserung" |
@skejcikowski You also needed a custom ControlValueAccessor previously to be able to use custom components with |
@zoechi yes I know this, and I'am using ControlValueAccessor's in my custom form components. But with the new forms it doesnt work anymore. Does anybody know when to expect the update ? |
@zoechi This is the appropriate channel - thats the Problem: "Name attribute must be set if ngModel ..." Not the control value accessor |
Like @wrldtrvllr and @mlittrell, I've been using dynamically generated inputs. But this raises the question what use-case there is for forms that cannot serialize their own value.
Kara's "if you want ngModel to register with the parent form, the name attribute is required" still holds, but in these cases, you may not care about registering the inputs as part of a serializable form. So I see two proposed alternatives:
The former suggestion surprises me, since not wrapping inputs in form elements would under some circumstances lead to the Right now I've just added names on a few inputs to make the error go away, but it's a bit silly since the names/serialization are not actually used. |
Thank you all for the great feedback - very helpful! Here's how we are thinking about it: In the case that you don't want to register a form control, you currently have a few options: 1 - Use ngModel outside the context of a form tag. This will never throw. <input [(ngModel)]="person.food"> 2 - Use an <form ngNoForm>
<input [(ngModel)]="person.food">
</form> Unfortunately, neither of these approaches are appropriate for the use case a few of you brought up where you might want some form controls registered in a form but not others. We should definitely support this case, so thanks for bringing it up. However, there are a few ways to approach this, and when considering a solution, dropping the error entirely is not ideal for two reasons: 1- It's not clear what's wrong if the name attribute is missing We want to ensure a good developer experience for those starting out with forms. Having the form silently fail to pick up a form control's value and validation state in some cases is confusing. It appears that the forms module is simply broken. Throwing a friendly error is much more explicit, and provides immediate feedback to the developer about how to fix the form. 2- The "name" attribute becomes the gatekeeper for form registration It seems arbitrary that the presence of a "name" attribute is what dictates the form control's relationship to its parent form. Currently, it's clear that the ngModel directive confers form functionality like validation state. If the "name" attribute controls the input's registration with its parent, then it muddies that concept and causes confusion about the relative effects of adding ngModel vs. a name (e.g. can you use the "name" attribute without ngModel, since it is responsible for form registration?) Solution: <form>
<input [(ngModel)]="person.food" [ngModelOptions]="{standalone: true}">
</form> It is preferable to have developers explicitly and deliberately indicate that they'd like to override the default behavior, rather than making an assumption based on the absence of an attribute. Using ngModelOptions is a natural choice because it is a clear extension of ngModel (rather than a distinct attribute or directive). This is a bit more boilerplate to write for these special controls, but it seems like this is an acceptable tradeoff given that this is the less common use case. This way, developers can still create special standalone controls, but the standard developer experience is not degraded. See PR: #9522 |
@kara Could you please rethink the name "standalone". It leaves me standing alone. From reading it I absolutely cannot infer what it means without the explanation you've given. Wouldn't be
more in line with terminology used elsewhere for forms? You might notice that these properties use |
In retrospect, I think my 'serialize' terminology wasn't so great either, since this seems more about getting the info into a JS object rather than making that object into a string. |
For anyone having trouble with the name attribute affecting other checkboxes in a loop, I am using this temporary workaround: Create the for loop: Give it a unique name based on index: Interpolation seems to do the trick. |
If Serializing to JSON should be an opt in approach (by providing Having to specify |
I discovered that if the form tag has a ngIf directive the error will vanish. So if you want to use form control validation and binding to value to model you could have something like:
|
Uh-oh, that's definitely shorter, but now it might be considered a bug instead of a feature and get fixed. :P |
All changes to the Forms API were good, except this one, the most ugly change. Still don't understand why option 'standalone' can't be set by default, when input element don't have a name. |
@e-oz @kara: Idea: what if we could get an application/module-wide boolean setting injected by DI to toggle this default? That way perhaps it might be possible to satisfy both new and experienced users? |
I have better idea: we can use string value of the |
Hm, kinda on the fence about it, implementation considerations aside. That said, technically the ideas aren't mutually exclusive; I suppose any alternative settings could just be another option. We don't need to change the default just to be able to add other options. |
Hello kara in your next tutorial please explain more about |
Ok I believe the name thing in forms is for Testability, so that the function in the component receives an object instead of simply modeling into a public object in class (easier to write tests), I forgot you nerds like that unit test thing. |
Ok, I've taught myself a bit more of ng2 forms and it appears as the name is used solely for naming a in-form field that angular can get to retrieve validation data, it should be optional, as the user might not need validation, and it shouldn't be necessary to specify ngNoForm or ngModelOptions standalone to true, angular could detect its a standalone by checking if name is undefined |
@felyperennan you should read Kara's responses here to get a sense of their considerations. |
Yeah, I've been reading this through, I understand the reasons and I'll be using ngNoForm or ngOptions adequately, it was never necessary in angularjs 1 and it used to "just work". id be looking for a more global configuration where ngforms behavior could be tweaked, but that's far fetched and I understand now. Thanks. |
@felyperennan: If it's any consolence, I'd personally managed to work around having to manually specify this extra attribute by abstracting the check away into a Pug mixin. But yeah, then you might need to use that. |
Hi, |
@kara sir,i have tried both your solution but still got error i am using [ngModelOptions]="{standalone: true}" on please tell me sir how to fix this error? |
use ngNoForm in the form tag and also [ngModelOptions]="{standalone: true}" |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
feature request
Current behavior
If opted into the new forms and I have code like this:
And this throws an error:
ORIGINAL EXCEPTION: Name attribute must be set if ngModel is used within a form.
Expected/desired behavior
I'd like to be able to use html forms and submit capabilities (such as submitting with the enter key) without having to specify a name (and use FormGroups and FormControls) for my ngModel bound inputs.
The text was updated successfully, but these errors were encountered: