-
Notifications
You must be signed in to change notification settings - Fork 27.4k
feat(input): interpolates form input name attrs for ngModel #4791
Conversation
It would be cool to be able to limit parsing/interpolation to only accept types like string/number for this, and have everything else be the empty string --- But I guess that's complicated, so this is the simplest way to do it. I don't know how valuable this is to other developers, but it seems to be useful to at least one person. |
+1 |
I had thought So, updating the |
I'm sorry, but I wasn't able to verify your CLA signature. CLA signature is required for any code contributions to AngularJS. Please sign our CLA and ensure that the CLA signature email address and the email address in this PR's commits match. If you signed the CLA as a corporation, please let me know the company's name. Thanks a bunch! PS: If you signed the CLA in the past then most likely the email addresses don't match. Please sign the CLA again or update the email address in the commit of this PR. |
1 similar comment
I'm sorry, but I wasn't able to verify your CLA signature. CLA signature is required for any code contributions to AngularJS. Please sign our CLA and ensure that the CLA signature email address and the email address in this PR's commits match. If you signed the CLA as a corporation, please let me know the company's name. Thanks a bunch! PS: If you signed the CLA in the past then most likely the email addresses don't match. Please sign the CLA again or update the email address in the commit of this PR. |
CLA signature verified! Thank you! Someone from the team will now triage your PR and it will be processed based on the determined priority (doc updates and fixes with tests are prioritized over other changes). |
In the mean time, or in case this is never merged, I wrote a plnkr the other showing how you could get this functionality with separate directives, or by decorating the existing ngModel and form directives http://plnkr.co/edit/VnHHEe?p=preview (this version decorates ngModelDirective and formDirective to provide this functionality) |
02dc2aa
to
fd2d6c0
Compare
Interpolates the form controll attribute name, so that dynamic form controls (such as those rendered in an ngRepeat) will always have their expected interpolated name. Closes angular#4791
Your code breaks with the ngRepeat + $index usecase. |
how does it "break", you haven't explained this. There are demonstrations of it being used exactly with ngRepeat + $index --- yes, the $index doesn't change, but this is fine |
So what happens then if the name value isn't present at the time of interpolation? You may end up getting an undefined value. |
You end up getting the empty string if it's undefined at the time of interpolation. Anyways, I've added a patch which renames the form control, but honestly nobody has ever asked for this, so I don't think we actually need it until someone does. The "support all the use cases and never ship" thing just doesn't seem sensible here |
Anyways, this does have some safety checks in that it requires form[oldName] to equal the control which is being renamed, which can potentially break things if there are multiple form controls whose name is the empty string. Lets worry about that when people say it's breaking their apps, really |
Okay, added another one which supports renaming forms |
I still kind of feel like this is more feature than people have really asked for and it's probably better to take it one step at a time, but it's in 3 separate commits so we can think about it all separately. @tbosch can you review as well? |
} else { | ||
controller.$name = alias; | ||
} | ||
}); | ||
} | ||
if (parentFormCtrl) { | ||
formElement.on('$destroy', function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should invoke unobserveName()
here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no need to since all watchers are removed when the scope is destroyed. Internally attr.$observe
uses $scope.$watch
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not exactly --- the observers collection stays alive afaik. The attribute interpolation watches are removed automatically though, this is true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's probably better to unobserve manually rather than accidentally risk keeping a reference alive
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whatever makes you guys happy :>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't add unobserve here, as we don't have it at similar places in the code neither and it confuses the reader (ask myself: "why here and not at the other places"...)
58dd9ae
to
1b59793
Compare
Interpolates the form controll attribute name, so that dynamic form controls (such as those rendered in an ngRepeat) will always have their expected interpolated name. Closes angular#4791
I think the only thing missing is tests (and possibly functionality) for select controls |
@@ -127,6 +128,23 @@ function FormController(element, attrs, $scope, $animate) { | |||
} | |||
}; | |||
|
|||
// Private API: rename a form control | |||
form.$$renameControl = function(control, newName) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be simplified to:
var oldName = control.$name;
if (form[oldName] === control) {
delete form[oldName];
}
form[newName] = control;
control.$name = newName;
LGTM when my comments are resolved. |
Interpolates the form controll attribute name, so that dynamic form controls (such as those rendered in an ngRepeat) will always have their expected interpolated name. Closes angular#4791 feat(input): rename form controls when name is updated feat(form): support dynamic form validation test(select): add tests for form control interpolation in selectDirective
some comments are addressed --- code is simplified a bit. If it looks good to land I will fix up the commit message and get it into this release. |
}); | ||
|
||
|
||
it('should interpolate input names (number)', function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is not needed, as the change is not dependent on the input type...
Interpolates the form and form control attribute name, so that dynamic form controls (such as those rendered in an ngRepeat) will always have their expected interpolated name. The control will be present in its parent form controller with the interpolated property name, and this name can change when the interpolated value changes. Closes angular#4791
Interpolates the form and form control attribute name, so that dynamic form controls (such as those rendered in an ngRepeat) will always have their expected interpolated name. The control will be present in its parent form controller with the interpolated property name, and this name can change when the interpolated value changes. Closes angular#4791
@frankhuster / @niargh has brought up an issue with using the
$index
of a repeated element for the name attribute of a form input.I don't know how common of a use-case it is, but it seems not especially harmful to do a one-time interpolation in post-link.
It shouldn't be a breaking change unless people are using interpolation markers in their names.