2013-06-13 13 views
16

Ho un modulo in una pagina. All'interno del modulo ho diversi controlli che hanno bisogno di visualizzare una finestra di dialogo di salvataggio quando il modulo è sporco, cioè forma. $ Dirty = true. Tuttavia ci sono alcuni controlli di navigazione nel modulo che non voglio sporcare il modulo. Supponiamo che io non possa spostare il controllo fuori dal modulo.

vedere: http://plnkr.co/edit/bfig4B

Come faccio a fare la casella di selezione non sporca la forma?

risposta

7

Angolare imposta il modulo solo se il controllo è intatto. Quindi il trucco qui è impostare $ pristine sul controllo su false. Puoi farlo in un timeout nel controller.

vedere: http://plnkr.co/edit/by3qTM

+0

Grazie mille! – cheeesus

+0

Quando premo lo spazio nella casella di testo, il modulo non diventa sporco, – Developer

24

Ecco una versione di risposta @ di acacia con una direttiva e non utilizzando $ timeout. Ciò manterrà i tuoi controllori più puliti.

.directive('noDirtyCheck', function() { 
    // Interacting with input elements having this directive won't cause the 
    // form to be marked dirty. 
    return { 
    restrict: 'A', 
    require: 'ngModel', 
    link: function(scope, elm, attrs, ctrl) { 
     ctrl.$pristine = false; 
    } 
    } 
}); 

poi usarlo nella vostra forma in questo modo:

<input type="text" name="foo" ng-model="x.foo" no-dirty-check> 
+1

Questa è un'implementazione eccezionale, ma soffre del problema @dmitankin menzionato con il modulo. $ SetPristine(). –

12

Impostare la proprietà incontaminata $ false, solo quando l'inizializzazione, funziona fino a quando si chiama $ setPristine() sul modulo. Quindi il tuo controllo ha il suo valore di $ precedente su true e la modifica del valore dell'input renderebbe il tuo modulo sporco. Per evitare che, impostare il $ incontaminata sulla messa a fuoco:

link: function(scope, elm, attrs, ctrl) { 
    elm.focus(function() { 
     ctrl.$pristine = false; 
    }); 
} 
12

ho usato la soluzione @ di pensare troppo, ma ha incontrato il problema menzionato da @dmitankin. Tuttavia, non volevo collegare un gestore all'evento di messa a fuoco. Così, invece, ho cercato di scavalcare la proprietà originaria di $ e costringerla a restituire false sempre. Ho finito per utilizzare Object.defineProperty che non è supportato in IE8 e sotto. Ci sono workarounds per fare questo in quei browser legacy, ma non ho bisogno di loro, in modo che non fanno parte della mia soluzione qui di seguito:

(function() { 
    angular 
     .module("myapp") 
     .directive("noDirtyCheck", noDirtyCheck); 

    function noDirtyCheck() { 
     return { 
      restrict: 'A', 
      require: 'ngModel', 
      link: function (scope, elem, attrs, ctrl) { 
       var alwaysFalse = { 
        get: function() { return false; }, 
        set: function() { } 
       }; 
       Object.defineProperty(ctrl, '$pristine', alwaysFalse); 
       Object.defineProperty(ctrl, '$dirty', alwaysFalse); 
      } 
     }; 
    } 
})(); 

Sono anche imperativi $ sporca in modo che non può essere impostata come sporco

+0

L'unica soluzione che funzionava in modo affidabile quando si utilizza 'form. $ SetPristine()' ad un certo punto. –

0

Mi sono imbattuto in alcuni problemi con che l'attuazione, ecco la mia (più complesso):

app.directive('noDirtyCheck', [function() { 
 
     // Interacting with input elements having this directive won't cause the 
 
     // form to be marked dirty. 
 
     // http://stackoverflow.com/questions/17089090/prevent-input-from-setting-form-dirty-angularjs 
 
     return { 
 
      restrict: 'A',   
 
      require: ['^form', '^ngModel'], 
 

 
      link: function (scope, element, attrs, controllers) { 
 
       var form = controllers[0]; 
 
       
 
       var currentControl = controllers[1]; 
 

 
       var formDirtyState = false; 
 

 
       var manualFocus = false; 
 

 
       element.bind('focus',function() { 
 
        manualFocus = true; 
 
        if (form) {       
 
         window.console && console.log('Saving current form ' + form.$name + ' dirty status: ' + form.$dirty); 
 
         formDirtyState = form.$dirty; // save form's dirty state 
 
        } 
 
       }); 
 
       
 
       element.bind('blur', function() { 
 
        if (currentControl) { 
 
         window.console && console.log('Resetting current control (' + currentControl.$name + ') dirty status to false (called from blur)'); 
 
         currentControl.$dirty = false; // Remove dirty state but keep the value 
 
         if (!formDirtyState && form && manualFocus) { 
 
          window.console && console.log('Resetting ' + form.$name + ' form pristine state...'); 
 
          form.$setPristine(); 
 
         } 
 
         manualFocus = false; 
 
         //   scope.$apply(); 
 
        } 
 
       }); 
 
      } 
 
     }; 
 
    }]);

+1

Chi ha implementato l'implementazione e quali problemi ha riscontrato? –

0

Questa è la mia risposta definitiva. Fondamentalmente angolare chiama internamente la funzione dello NgModelController quando l'input è interagito con, quindi basta ignorarlo!

app.directive('noDirtyCheck', function() { 
    return { 
    restrict: 'A', 
    require: 'ngModel', 
    link: postLink 
    }; 
    function postLink(scope, iElem, iAttrs, ngModelCtrl) { 
    ngModelCtrl.$setDirty = angular.noop; 
    } 
}) 
Problemi correlati