feat(form.FormController): add $getControls()

Closes #16601
Fixes #14749
Closes #14517
Closes #13202
This commit is contained in:
Martin Staffa
2018-06-18 16:02:19 +02:00
committed by GitHub
parent d7d64cc363
commit 5b11145473
2 changed files with 71 additions and 0 deletions
+25
View File
@@ -4,6 +4,7 @@
*/
var nullFormCtrl = {
$addControl: noop,
$getControls: valueFn([]),
$$renameControl: nullFormRenameControl,
$removeControl: noop,
$setValidity: noop,
@@ -159,6 +160,30 @@ FormController.prototype = {
control.$$parentForm = this;
},
/**
* @ngdoc method
* @name form.FormController#$getControls
* @returns {Array} the controls that are currently part of this form
*
* @description
* This method returns a **shallow copy** of the controls that are currently part of this form.
* The controls can be instances of {@link form.FormController `FormController`}
* ({@link ngForm "child-forms"}) and of {@link ngModel.NgModelController `NgModelController`}.
* If you need access to the controls of child-forms, you have to call `$getControls()`
* recursively on them.
* This can be used for example to iterate over all controls to validate them.
*
* The controls can be accessed normally, but adding to, or removing controls from the array has
* no effect on the form. Instead, use {@link form.FormController#$addControl `$addControl()`} and
* {@link form.FormController#$removeControl `$removeControl()`} for this use-case.
* Likewise, adding a control to, or removing a control from the form is not reflected
* in the shallow copy. That means you should get a fresh copy from `$getControls()` every time
* you need access to the controls.
*/
$getControls: function() {
return shallowCopy(this.$$controls);
},
// Private API: rename a form control
$$renameControl: function(control, newName) {
var oldName = control.$name;
+46
View File
@@ -1200,6 +1200,52 @@ describe('form', function() {
});
});
describe('$getControls', function() {
it('should return an empty array if the controller has no controls', function() {
doc = $compile('<form name="testForm"></form>')(scope);
scope.$digest();
var formCtrl = scope.testForm;
expect(formCtrl.$getControls()).toEqual([]);
});
it('should return a shallow copy of the form controls', function() {
doc = $compile(
'<form name="testForm">' +
'<input ng-model="named" name="foo">' +
'<div ng-form>' +
'<input ng-model="named" name="foo">' +
'</div>' +
'</form>')(scope);
scope.$digest();
var form = doc,
formCtrl = scope.testForm,
formInput = form.children('input').eq(0),
formInputCtrl = formInput.controller('ngModel'),
nestedForm = form.find('div'),
nestedFormCtrl = nestedForm.controller('form'),
nestedInput = nestedForm.children('input').eq(0),
nestedInputCtrl = nestedInput.controller('ngModel');
var controls = formCtrl.$getControls();
expect(controls).not.toBe(formCtrl.$$controls);
controls.push('something');
expect(formCtrl.$$controls).not.toContain('something');
expect(controls[0]).toBe(formInputCtrl);
expect(controls[1]).toBe(nestedFormCtrl);
var nestedControls = controls[1].$getControls();
expect(nestedControls[0]).toBe(nestedInputCtrl);
});
});
it('should rename nested form controls when interpolated name changes', function() {
scope.idA = 'A';