From 87b63ac4ed2f7c935a9e6cf3f88c6335b391f820 Mon Sep 17 00:00:00 2001 From: Yaroslav Ulanovych Date: Wed, 17 Apr 2013 15:55:53 +0300 Subject: [PATCH] fix(ngModel): handle interpolated names for ngModel Fix that controls with interpolated names don't publish themselves to the form, cause the name isn't known at publishing time. Refers #1404 --- src/ng/directive/input.js | 16 +++++++++++++++- test/ng/directive/formSpec.js | 18 ++++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index 2574360cc4e1..0803338444c5 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -1110,7 +1110,21 @@ var ngModelDirective = function() { var modelCtrl = ctrls[0], formCtrl = ctrls[1] || nullFormCtrl; - formCtrl.$addControl(modelCtrl); + // Support of the interpolation in the name attribute, + // when the name changes, the control is republished in the form. + // We rely on the behaviour of the attribute interpolation directive, + // which sets the value to undefined during compilation. + if (attr.name) { + formCtrl.$addControl(modelCtrl); + } else { + attr.$observe('name', function(name) { + if (modelCtrl.$name) { + formCtrl.$removeControl(modelCtrl); + } + modelCtrl.$name = name; + formCtrl.$addControl(modelCtrl); + }); + } element.bind('$destroy', function() { formCtrl.$removeControl(modelCtrl); diff --git a/test/ng/directive/formSpec.js b/test/ng/directive/formSpec.js index 0e3695cd1ff3..6207048376ee 100644 --- a/test/ng/directive/formSpec.js +++ b/test/ng/directive/formSpec.js @@ -111,8 +111,7 @@ describe('form', function() { expect(scope.formB.$error.required).toBe(false); }); - - it('should publish widgets', function() { + it('should publish widgets with static names', function() { doc = jqLite('
'); $compile(doc)(scope); @@ -124,6 +123,21 @@ describe('form', function() { expect(widget.$invalid).toBe(false); }); + it('should publish widgets with dynamic names', function() { + doc = jqLite('
'); + $compile(doc)(scope); + + scope.name = 'w1'; + scope.$digest(); + var widget = scope.form.w1; + expect(widget).toBeDefined(); + + scope.name = 'w2'; + scope.$digest(); + expect(scope.form.w1).toBeUndefined(); + expect(scope.form.w2).toBeDefined(); + expect(scope.form.w2).toBe(widget); + }); describe('preventing default submission', function() {