2014-09-13 17 views
6

Ho un AngularJS nidificati formano in questo modo:Set AngularJS nidificate moduli per presentare

<form name="parentForm" ng-submit="submit()"> 
    <input name="parentInput" type="text"> 
    <ng-include src="childForm.html" ng-form="childForm"></ng-include> 
    <button type="submit">Submit</submit> 
</form> 

Ed ecco childForm.html

<input name="childInput" type="text"> 

per motivi estranei alla questione, non posso unire i moduli padre e figlio: devono essere due file separati.

Ora, quando l'utente fa clic sul pulsante di invio, la convalida viene applicata correttamente a parentForm e childForm. Tuttavia, solo il modulo padre ha il flag $ submit impostato su true, il che è problematico poiché lo sto utilizzando per attivare la visualizzazione di determinati messaggi di errore. Non voglio che il modulo figlio verifichi se il modulo padre è $ inviato, poiché sono due file separati. L'unica opzione che mi è venuta in mente è che il metodo submit() chiama $ setSubmitted() sul modulo figlio, il che è scomodo poiché ora il modulo padre deve fare riferimento direttamente al modulo figlio. C'è un modo migliore per impostare $ del modulo figlio inviato a true?

+0

come è che: "innescare il visualizzazione di determinati messaggi di errore "? –

risposta

2

Questa era la mia soluzione a questo problema (e scommetto che qualcuno può fare questo più bella)

ho fatto una direttiva ngForm che attaccato un ascoltatore,

.directive('ngForm', function(){ 
    return { 
     restrict: 'AE', 
     require: 'form', 
     link: function(scope,element,attrs,form){ 
      var parentForm = element.parent().controller('form'); 
      if(parentForm){ 
       scope.$on('parentFormSubmitted',function(event){ 
        form.$setSubmitted(); 
       }); 
      } 
     } 
    }; 
}) 

Poi nel controller del form padre eseguo questo pezzo di codice quando il modulo viene inviato

$scope.submit = function(){ 
    $scope.$broadcast('parentFormSubmitted'); 
} 
5

Come estensione della soluzione di Meeker, si potrebbe ottenere la $broadcast implicitamente con l'aggiunta di un orologio al form padre:

.directive('form', function() { 
    return { 
    restrict: 'E', 
    require: 'form', 
    link: function(scope, elem, attrs, formCtrl) { 

     scope.$watch(function() { 
     return formCtrl.$submitted; 
     }, function(submitted) { 
     submitted && scope.$broadcast('$submitted'); 
     }); 
    } 
    }; 
}) 

.directive('ngForm', function() { 
    return { 
    restrict: 'EA', 
    require: 'form', 
    link: function(scope, elem, attrs, formCtrl) { 

     scope.$on('$submitted', function() { 
     formCtrl.$setSubmitted(); 
     }); 
    } 
    }; 
}) 
+1

Nota: funziona solo se è stato modificato 'formCtrl. $ Submitted'. Quindi potrebbe non funzionare con 'ng-form' nidificato dinamico. – stevemao

3

C'è un problema nel bug tracker di angolare per questo https://github.com/angular/angular.js/issues/10071. Un commento suggerisce questa soluzione nel frattempo:

// sets all children ng-forms submitted (no such default functionality) 
function setSubmitted(form) { 
    form.$setSubmitted(); 
    angular.forEach(form, function(item) { 
     if(item && item.$$parentForm === form && item.$setSubmitted) { 
      setSubmitted(item); 
     } 
    }); 
} 

// so ie. instead of scope.form.$setSubmitted(); use:  
setSubmitted(scope.form); 

Un problema con questo approccio è che ogni forma aggiunti dinamicamente non copierà stato iniziale del loro genitore. Sto usando questo quando si aggiungono le forme in modo dinamico:

function onNewChildForm (form) { 
    if(form.$$parentForm && form.$$parentForm.$submitted) { 
     setFormSubmitted(form); 
    } 
} 
0

inizialmente ho usato soluzione Scarlz', ma nella mia situazione ho avuto diversi nidificati ng-form s che vengono creati/distrutti da ng-if.

Invece di utilizzare ng-show e trattare con i dati eventualmente esistenti, ho modificato la soluzione Scarlz' di utilizzare l'evento Invia invece di guardare la form.$submitted proprietà

function ParentFormThatSubmits() { 
 
    return { 
 
     restrict: 'E', 
 
     require: 'form', 
 
     link: function(scope, elem, attrs, formCtrl) { 
 
     elem.on('submit', function() { 
 
      var submitted = formCtrl.$submitted; 
 
      if(submitted) { 
 
      scope.$broadcast('$submitted'); 
 
      } 
 
     }); 
 
     } 
 
    }; 
 
    } 
 

 
    function ChildFormThatSubmits() { 
 
    return { 
 
     restrict: 'EA', 
 
     require: 'form', 
 
     link: function(scope, elem, attrs, formCtrl) { 
 
     scope.$on('$submitted', function() { 
 
      formCtrl.$setSubmitted(); 
 
      scope.$apply(); 
 
     }); 
 
     } 
 
    }; 
 
    } 
 

 
    angular.module('appModule') 
 
    .directive('form', ParentFormThatSubmits) 
 
    .directive('ngForm', ChildFormThatSubmits);