otro index example dentro bootstrap angularjs validation angularjs-ng-repeat angularjs-ng-form

angularjs - index - Ng-repeat angular con ng-form, accediendo a la validación en el controlador



ng-< repeat angular (1)

Actualizado el 17-01-2017:

Como señala Leblanc Meneses en los comentarios, Angular 1.3 ahora admite la interpolación con las directivas form , ngForm y input .

Esto significa que usando expresiones para nombrar sus elementos:

<div ng-form="namesForm_{{$index}}" ng-repeat="name in names"> <input type="text" name="input_{{$index}}_0"></input> <!-- ... --> </div>

funcionará como se espera:

$scope[''namesForm_0''] $scope.namesForm_1 // Access nested form elements: $scope.namesForm_1.input_1_0 ...

Respuesta original para Angular <= 1.2:

Trabajar con formularios y ngFormController puede complicarse bastante rápido.

Debe tener en cuenta que puede agregar elementos y entradas de forma dinámica, pero no pueden nombrarse dinámicamente; la interpolación no funciona en las directivas ngForm o name .

Por ejemplo, si trataste de nombrar sus formularios anidados dinámicamente así:

<div ng-form="namesForm_{{$index}}" ng-repeat="name in names"> <!-- ... --> </div>

En lugar de hacer todos los formularios anidados disponibles en el ámbito de la siguiente manera: scope[''namesForm_0''] solo tendrías acceso a la única (última) forma con el nombre literal del scope[''namesForm_{{$index}}''] .

En su situación, necesita crear una directiva personalizada que se agregará junto con ngForm para manejar la configuración $pristine$ y $invalid para esa instancia de formulario.

JavaScript:

Esta directiva observará el estado $dirty de su forma para establecer la $validity para evitar el envío cuando está sucio y manejar el estado $pristine cuando se presiona el botón ''limpiar''.

app.directive(''formCleaner'', function(){ return { scope: true, require: ''^form'', link: function(scope, element, attr){ scope.clean = function () { scope.namesForm.$setPristine(); }; scope.$watch(''namesForm.$dirty'', function(isDirty){ scope.namesForm.$setValidity(''name'', !isDirty); }); } }; });

HTML:

Entonces, el único cambio en su HTML es agregar la directiva formCleaner .

Así que cambie su HTML original de esto:

<body ng-controller="MainCtrl"> <form name="mainForm" submit="submit()"> <h3>My Editable List</h3> <div ng-form="namesForm" ng-repeat="name in names"> <!-- ... --> </div> <button class="btn btn-default" type="submit">Submit</button> </form> </body>

a esto, agregando form-cleaner lado de ng-form :

<body ng-controller="MainCtrl"> <form name="mainForm" submit="submit()"> <h3>My Editable List</h3> <!-- Add the `form-cleaner` directive to the element with `ng-form` --> <div form-cleaner ng-form="namesForm" ng-repeat="name in names"> <!-- ... --> </div> <button class="btn btn-default" type="submit">Submit</button> </form> </body>

Aquí hay un Plunker actualizado que muestra el nuevo comportamiento: http://plnkr.co/edit/Lxem5HJXe0UCvslqbJr3?p=preview

Estoy tratando de generar una lista editable usando ng-repeat . Quiero recordarle al usuario que actualice las ediciones antes de continuar, así que estoy usando ng-form para crear ng-form "anidados" sobre la marcha porque la documentación dice que puedo usar la validación en estas entradas creadas dinámicamente.

Si bien eso parece funcionar dentro del HTML, no veo cómo acceder a esos formularios creados dinámicamente y campos de validación relacionados en el controlador. Específicamente, cuando el usuario cambia la entrada, uso la propiedad $ dirty del formulario para que aparezca un botón que le indique al usuario que realice los cambios. Hasta aquí todo bien. Sin embargo, una vez que se hayan confirmado los cambios, quiero $setPristine() en el campo para indicar que se han establecido los cambios. Puede haber otras formas de garantizar que los cambios se confirmen en cada entrada antes de permitir el compromiso del formulario principal, pero esto fue lo mejor que se me ocurrió.

Desafortunadamente, a pesar de que la documentación dice que si le doy el nombre ng-form, se propagará al objeto $scope , no puedo encontrar la manera de acceder a él. $scope.dynamic_form no está definido.

Aquí hay un plunker que muestra lo que quiero decir:

plnk

¡Gracias!

[EDITAR] Solo para agregar al problema, lo que funciona para este ejemplo específico es agregar al ng-click en la entrada creada dinámicamente:

ng-click="namesForm.name.$setPristine();clean()"

Pero todavía no tengo acceso a la forma creada dinámicamente en el controlador. Me gustaría, por ejemplo, agregar un vigilante al namesForm.name.$pristine para que pueda establecer el mainForm.$setValidity(false) siempre que el mainForm.$setValidity(false) sea $dirty para evitar que el usuario envíe el formulario principal hasta todos los cambios de subformulario se han confirmado.

Entonces, en pocas palabras, el problema es cómo acceder en un controlador principal los valores de validación de un ngForm anidado creado dinámicamente.