1

реализации Детали:проверка несохраненных данных формы в angularjs (несколько форм с использованием UI-маршрутизатор)

Я использую UI-маршрутизатор для загрузки формы страницы в UI-просмотра дел. Я сослался на отличный пример на Andres Ekdahi. Как я могу выполнить грязную проверку на нескольких формах с помощью той же директивы?

form1

<form name="myForm" ng-controller="Controller" confirm-on-exit> 

form2

<form name="iForm" ng-controller="Controller" confirm-on-exit ng-model="myModel"> 

app.js (директива)

myApp.directive('confirmOnExit', function() { 
     return { 
      link: function($scope, elem, attrs) { 
       // condition when back page is pressed 
       window.onbeforeunload = function(){ 
        if ($scope.myForm.$dirty) { 
         return "The formI is dirty, do you want to stay on the page?"; 
        } 
       } 
       // condition when user try to load other form (via icons) 
       $scope.$on('$stateChangeStart', function(event, next, current) { 
        if ($scope.myForm.$dirty) { 
         if(!confirm("myForm. Do you want to continue ?")) { 
          event.preventDefault(); 
         } 
        } 

        if ($scope.iForm.$dirty) { 
         if(!confirm("iform. Do you want to continue ?")) { 
          event.preventDefault(); 
         } 
        } 
       }); 
      } 
     }; 
    }); 

Ошибка:

Первый раз при загрузке страницы, грязного значение $ является ложный. и я заполняю детали формы и щелкаю третий значок (файл), и я получаю ошибку для второй формы грязной проверки if ($scope.iForm.$dirty) и для $dirty в предупреждении.

angular.js:12520 TypeError: Cannot read property '$dirty' of undefined 

и

<form name="iForm" ng-controller="Controller" confirm-on-exit="" ng-model="myModel" class="ng-pristine ng-untouched ng-valid ng-scope"> 

Демо: Plunker

ответ

1

сделать вас директиву более проще, взяв его из name атрибута form, так что только одно условие будет лежать внутри директивы & он может повторно использоваться во многих местах.

<form name="myForm" ng-controller="Controller" confirm-on-exit> 

Код

var form = $scope[attrs.name]; //which will take out form name & do search that inside scope 
if (form.$dirty) { //form object would always exist, to make sure you could also add one more check `form &&` 
    if(!confirm("myForm. Do you want to continue ?")) { 
     event.preventDefault(); 
    } 
} 

Demo here

+0

Можете ли вы объяснить мне, что ищет '$ scope [attrs.name]' look? применяется ли это только для изменения данных формы или для любого пользователя? –

+1

@ Mad-D, который выведет имя формы и будет искать область 'controlName' внутри контроллера. –

+0

Спасибо, сэр, я думаю, это именно то, что мне нужно было сделать. –

1

проверить, если форма существует, прежде чем проверить, если он загрязнен. Есть ли что-то вроде

if ($scope.myForm && $scope.myForm.$dirty) { 
    if(!confirm("myForm. Do you want to continue ?")) { 
     event.preventDefault(); 
    } 
} 

if ($scope.iForm && $scope.iForm.$dirty) { 
    if(!confirm("iform. Do you want to continue ?")) { 
     event.preventDefault(); 
    } 
} 
+0

спасибо, ваш ответ является правильным, а также. Мне просто нужно было проверить существование формы. –

2

Там более простой способ.

Просто требуется ваша директива будет размещена на элементе формы и доступа к контроллеру формы через функцию связи:

myApp.directive('confirmOnExit', function() { 
     return { 
      require: 'form', 
      link: function($scope, elem, attrs, formController) { 
       // condition when back page is pressed 
       window.onbeforeunload = function(){ 
        if (formController.$dirty) { 
         return "The form '" + formController.$name + "' is dirty, do you want to stay on the page?"; 
        } 
       } 
       // condition when user try to load other form (via icons) 
       $scope.$on('$stateChangeStart', function(event, next, current) { 
        if (formController.$dirty) { 
         if(!confirm(formController.$name + ". Do you want to continue ?")) { 
          event.preventDefault(); 
         } 
        } 
       }); 
      } 
     }; 
    });