Question

Je suis en train de générer une liste modifiable à l'aide de ng-repeat.Je tiens à rappeler à l'utilisateur de mettre à jour les modifications avant de passer, donc je suis en utilisant ng-form pour créer des "imbriqués" formulaires à la volée, car la documentation dit que je peux ensuite utiliser la validation de ces créé dynamiquement entrées.

Tout qui semble fonctionner dans le code HTML, je ne vois pas comment accéder à ces créé dynamiquement les formulaires et validation de champs dans le contrôleur.Plus précisément, lorsque l'utilisateur modifie l'entrée-je utiliser le formulaire $sale propriété d'apporter un bouton pour indiquer à l'utilisateur pour valider les modifications.Pour l'instant, donc bon.Cependant, une fois que les modifications sont validées que je veux $setPristine() sur le champ pour indiquer que les changements ont été mis en.Il y a peut-être d'autres façons de s'assurer que les changements sont engagés sur chaque entrée avant que je permettre le formulaire principal commis, mais c'était le mieux que je pouvais venir.

Malheureusement, même si la documentation dit que si j'ai le nom de la ng-forme, il sera propagée à l' $scope objet, je ne peux pas trouver un moyen d'y accéder. $scope.dynamic_form n'est pas défini.

Voici une plunker montrant ce que je veux dire:

plnk

Merci!

[EDIT] Juste pour ajouter à la question, ce n'travail pour cet exemple précis est à ajouter à la ng-click sur le créé dynamiquement d'entrée:

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

Mais je n'ai toujours pas accès à l'dynamiquement formulaire créé dans le contrôleur.Je voudrais, par exemple, pour ajouter un observateur à l' namesForm.name.$pristine afin que je puisse régler le mainForm.$setValidity(false) chaque fois que le sous-formulaire est $dirty pour empêcher l'utilisateur de soumettre le formulaire principal jusqu'à ce que tous les sous-formulaire de modifications ont été validées.

Donc, en un mot, la question est de savoir comment accéder à un parent contrôleur de la validation des valeurs de a créé dynamiquement imbriquée ngForm?

Était-ce utile?

La solution

Mise à jour 2015-01-17:

Comme l'a souligné Leblanc Meneses dans les commentaires Angulaire 1.3 prend désormais en charge l'interpolation avec form, ngForm et input les directives.

Cela signifie que l'utilisation des expressions pour nommer vos éléments:

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

fonctionne comme prévu:

$scope['namesForm_0']
$scope.namesForm_1

// Access nested form elements:
$scope.namesForm_1.input_1_0
...

Original de la réponse Angulaire <= 1.2:

Travailler avec les formulaires et les ngFormController peut se complique assez rapidement.

Vous devez être conscient que vous pouvez ajouter dynamiquement des éléments de formulaire et des intrants, mais ils ne peuvent pas être dynamiquement nommé - l'interpolation ne fonctionne pas dans le ngForm ou name les directives.

Par exemple, si vous avez essayé de nom votre des formulaires imbriqués de façon dynamique comme ceci:

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

Au lieu de faire de toutes les formes imbriquées disponible sur la portée comme ceci: scope['namesForm_0'] vous n'avez accès qu'à la seule (et dernière) forme avec le nom littéral scope['namesForm_{{$index}}'].

Dans votre situation, vous devez créer un personnalisé directive qui sera ajouté avec ngFormà gérer $pristine$ et $invalid pour cette instance du formulaire.

JavaScript:

Cette directive permettra de regarder la $dirty de son état de forme à définir la $validity pour éviter la soumission quand il est sale, et la poignée de réglage de la $pristine de l'état lors de la "propreté" du bouton est pressé.

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:

Ensuite, le seul changement dans votre code HTML, ajouter l' formCleaner la directive.

Afin de changer votre HTML d'origine de ceci:

<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>

pour ce, par l'ajout d' form-cleaner à côté 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>

Voici une mise à jour de Plunker montrant le nouveau comportement: http://plnkr.co/edit/Lxem5HJXe0UCvslqbJr3?p=preview

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top