From 11af046cde3fc1286a0a6297404bf9cd031711e6 Mon Sep 17 00:00:00 2001 From: Voorhoede_Maarten Date: Mon, 3 Feb 2014 18:39:27 +0100 Subject: [PATCH] feat(form): add `parent` parameter Makes it possible to: - disable the registration of a form in its parent form by specifying an empty or falsy value (preventing the propagation of validation, dirtiness and so on) - specify a custom parent form (that is not necessarily the parent in the DOM) via an Angular expression that is evaluated in the current scope If the parameter is not specified, the form directive will traverse up the DOM to locate a parent form as before this change, so current implementations will not break. --- src/ng/directive/form.js | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/ng/directive/form.js b/src/ng/directive/form.js index 86776ae7589f..266a2ddda054 100644 --- a/src/ng/directive/form.js +++ b/src/ng/directive/form.js @@ -47,13 +47,19 @@ var nullFormCtrl = { */ //asks for $scope to fool the BC controller module FormController.$inject = ['$element', '$attrs', '$scope']; -function FormController(element, attrs) { +function FormController(element, attrs, scope) { var form = this, - parentForm = element.parent().controller('form') || nullFormCtrl, + parentForm, invalidCount = 0, // used to easily determine if we are valid errors = form.$error = {}, controls = []; + if (isDefined(attrs.parent)) { + parentForm = scope.$eval(attrs.parent) || nullFormCtrl; + } else { + parentForm = element.parent().controller('form') || nullFormCtrl; + } + // init state form.$name = attrs.name || attrs.ngForm; form.$dirty = false; @@ -221,7 +227,10 @@ function FormController(element, attrs) { * * @param {string=} ngForm|name Name of the form. If specified, the form controller will be published into * related scope, under this name. - * + * @param {string=} parent Angular expression that points to a form that will be treated as parent + * form. If not specified, Angular will traverse up the DOM to locate a + * parent form by itself. If specified without a value (or if the expression + * evaluates falsy), the form will not register itself in a parent form. */ /** @@ -286,6 +295,10 @@ function FormController(element, attrs) { * * @param {string=} name Name of the form. If specified, the form controller will be published into * related scope, under this name. + * @param {string=} parent Angular expression that points to a form that will be treated as parent + * form. If not specified, Angular will traverse up the DOM to locate a + * parent form by itself. If specified without a value (or if the expression + * evaluates falsy), the form will not register itself in a parent form. * * @example @@ -361,12 +374,19 @@ var formDirectiveFactory = function(isNgForm) { }); } - var parentFormCtrl = formElement.parent().controller('form'), + var parentFormCtrl, alias = attr.name || attr.ngForm; if (alias) { setter(scope, alias, controller, alias); } + + if (isDefined(attr.parent)) { + parentFormCtrl = scope.$eval(attr.parent); + } else { + parentFormCtrl = formElement.parent().controller('form'); + } + if (parentFormCtrl) { formElement.on('$destroy', function() { parentFormCtrl.$removeControl(controller);