Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 5b11145

Browse files
authored
feat(form.FormController): add $getControls()
Closes #16601 Fixes #14749 Closes #14517 Closes #13202
1 parent d7d64cc commit 5b11145

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

src/ng/directive/form.js

+25
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55
var nullFormCtrl = {
66
$addControl: noop,
7+
$getControls: valueFn([]),
78
$$renameControl: nullFormRenameControl,
89
$removeControl: noop,
910
$setValidity: noop,
@@ -159,6 +160,30 @@ FormController.prototype = {
159160
control.$$parentForm = this;
160161
},
161162

163+
/**
164+
* @ngdoc method
165+
* @name form.FormController#$getControls
166+
* @returns {Array} the controls that are currently part of this form
167+
*
168+
* @description
169+
* This method returns a **shallow copy** of the controls that are currently part of this form.
170+
* The controls can be instances of {@link form.FormController `FormController`}
171+
* ({@link ngForm "child-forms"}) and of {@link ngModel.NgModelController `NgModelController`}.
172+
* If you need access to the controls of child-forms, you have to call `$getControls()`
173+
* recursively on them.
174+
* This can be used for example to iterate over all controls to validate them.
175+
*
176+
* The controls can be accessed normally, but adding to, or removing controls from the array has
177+
* no effect on the form. Instead, use {@link form.FormController#$addControl `$addControl()`} and
178+
* {@link form.FormController#$removeControl `$removeControl()`} for this use-case.
179+
* Likewise, adding a control to, or removing a control from the form is not reflected
180+
* in the shallow copy. That means you should get a fresh copy from `$getControls()` every time
181+
* you need access to the controls.
182+
*/
183+
$getControls: function() {
184+
return shallowCopy(this.$$controls);
185+
},
186+
162187
// Private API: rename a form control
163188
$$renameControl: function(control, newName) {
164189
var oldName = control.$name;

test/ng/directive/formSpec.js

+46
Original file line numberDiff line numberDiff line change
@@ -1200,6 +1200,52 @@ describe('form', function() {
12001200
});
12011201
});
12021202

1203+
describe('$getControls', function() {
1204+
it('should return an empty array if the controller has no controls', function() {
1205+
doc = $compile('<form name="testForm"></form>')(scope);
1206+
1207+
scope.$digest();
1208+
1209+
var formCtrl = scope.testForm;
1210+
1211+
expect(formCtrl.$getControls()).toEqual([]);
1212+
});
1213+
1214+
it('should return a shallow copy of the form controls', function() {
1215+
doc = $compile(
1216+
'<form name="testForm">' +
1217+
'<input ng-model="named" name="foo">' +
1218+
'<div ng-form>' +
1219+
'<input ng-model="named" name="foo">' +
1220+
'</div>' +
1221+
'</form>')(scope);
1222+
1223+
scope.$digest();
1224+
1225+
var form = doc,
1226+
formCtrl = scope.testForm,
1227+
formInput = form.children('input').eq(0),
1228+
formInputCtrl = formInput.controller('ngModel'),
1229+
nestedForm = form.find('div'),
1230+
nestedFormCtrl = nestedForm.controller('form'),
1231+
nestedInput = nestedForm.children('input').eq(0),
1232+
nestedInputCtrl = nestedInput.controller('ngModel');
1233+
1234+
var controls = formCtrl.$getControls();
1235+
1236+
expect(controls).not.toBe(formCtrl.$$controls);
1237+
1238+
controls.push('something');
1239+
expect(formCtrl.$$controls).not.toContain('something');
1240+
1241+
expect(controls[0]).toBe(formInputCtrl);
1242+
expect(controls[1]).toBe(nestedFormCtrl);
1243+
1244+
var nestedControls = controls[1].$getControls();
1245+
1246+
expect(nestedControls[0]).toBe(nestedInputCtrl);
1247+
});
1248+
});
12031249

12041250
it('should rename nested form controls when interpolated name changes', function() {
12051251
scope.idA = 'A';

0 commit comments

Comments
 (0)