diff --git a/src/directive/form.js b/src/directive/form.js index c3e6b21d1639..e3b937da5120 100644 --- a/src/directive/form.js +++ b/src/directive/form.js @@ -33,7 +33,7 @@ function FormController($scope, name) { $scope.$on('$destroy', function(event, widget) { if (!widget) return; - if (widget.widgetId) { + if (widget.widgetId && form[widget.widgetId] === widget) { delete form[widget.widgetId]; } forEach(errors, removeWidget, widget); @@ -60,6 +60,12 @@ function FormController($scope, name) { form.pristine = false; }); + $scope.$on('$newFormControl', function(event, widget) { + if (widget.widgetId && !form.hasOwnProperty(widget.widgetId)) { + form[widget.widgetId] = widget; + } + }); + // init state form.dirty = false; form.pristine = true; @@ -95,26 +101,6 @@ function FormController($scope, name) { } } -/** - * @ngdoc function - * @name angular.module.ng.$compileProvider.directive.form.FormController#registerWidget - * @methodOf angular.module.ng.$compileProvider.directive.form.FormController - * @function - * - * @param {Object} widget Widget to register (controller of a widget) - * @param {string=} alias Name alias of the widget. - * (If specified, widget will be accesible as a form property) - * - * @description - * - */ -FormController.prototype.registerWidget = function(widget, alias) { - if (alias && !this.hasOwnProperty(alias)) { - widget.widgetId = alias; - this[alias] = widget; - } -}; - /** * @ngdoc directive diff --git a/src/directive/input.js b/src/directive/input.js index ae3fea1c0de0..8eea48a3575b 100644 --- a/src/directive/input.js +++ b/src/directive/input.js @@ -750,8 +750,8 @@ var inputDirective = [function() { * @description * */ -var NgModelController = ['$scope', '$exceptionHandler', 'ngModel', - function($scope, $exceptionHandler, ngModel) { +var NgModelController = ['$scope', '$exceptionHandler', '$attrs', 'ngModel', + function($scope, $exceptionHandler, $attr, ngModel) { this.viewValue = Number.NaN; this.modelValue = Number.NaN; this.parsers = []; @@ -762,6 +762,7 @@ var NgModelController = ['$scope', '$exceptionHandler', 'ngModel', this.valid = true; this.invalid = false; this.render = noop; + this.widgetId = $attr.name; /** @@ -920,26 +921,22 @@ var ngModelDirective = [function() { inject: { ngModel: 'accessor' }, - require: ['ngModel', '^?form'], + require: 'ngModel', controller: NgModelController, - link: function(scope, element, attr, controllers) { - var modelController = controllers[0], - formController = controllers[1]; - - if (formController) { - formController.registerWidget(modelController, attr.name); - } + link: function(scope, element, attr, ctrl) { + // notify others, especially parent forms + scope.$emit('$newFormControl', ctrl); forEach(['valid', 'invalid', 'pristine', 'dirty'], function(name) { scope.$watch(function() { - return modelController[name]; + return ctrl[name]; }, function(value) { element[value ? 'addClass' : 'removeClass']('ng-' + name); }); }); element.bind('$destroy', function() { - scope.$emit('$destroy', modelController); + scope.$emit('$destroy', ctrl); }); } }; diff --git a/test/directive/inputSpec.js b/test/directive/inputSpec.js index d9f6b7b3bd63..54f3f7cda9f6 100644 --- a/test/directive/inputSpec.js +++ b/test/directive/inputSpec.js @@ -4,9 +4,11 @@ describe('NgModelController', function() { var ctrl, scope, ngModelAccessor; beforeEach(inject(function($rootScope, $controller) { + var attrs = {name: 'testAlias'}; + scope = $rootScope; ngModelAccessor = jasmine.createSpy('ngModel accessor'); - ctrl = $controller(NgModelController, {$scope: scope, ngModel: ngModelAccessor}); + ctrl = $controller(NgModelController, {$scope: scope, ngModel: ngModelAccessor, $attrs: attrs}); // mock accessor (locals) ngModelAccessor.andCallFake(function(val) { @@ -27,6 +29,8 @@ describe('NgModelController', function() { expect(ctrl.formatters).toEqual([]); expect(ctrl.parsers).toEqual([]); + + expect(ctrl.widgetId).toBe('testAlias'); });