1

実装の詳細:チェック(UI-ルータを使用して、複数のフォーム)

私は、UIビューのdivにフォームページをロードするために、UI-ルータを使用しています。私はAndres Ekdahiの素晴らしい例を参照しました。同じディレクティブを使用して複数のフォームで$ dirty checkを行うにはどうすればよいですか?

を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(); 
         } 
        } 
       }); 
      } 
     }; 
    }); 

エラー:ページのロードの

初めて、$汚い値であります偽です。私はフォームの詳細を記入して3番目のアイコン(ファイル)をクリックすると、2番目のフォームの汚れチェック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

のようなものは、それが多くの場所で再利用可能できる唯一の条件は、ディレクティブ&内に存在するように、あなたは、formname属性からそれを取ることによって、よりシンプルなディレクティブ確認してください。

<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]'が探していることを教えてもらえますか?フォームデータの変更やユーザーのクリックに対してのみ適用されますか? –

+1

@ Mad-Dはフォーム名を取り、コントローラスコープ内で 'formName'を検索します。 –

+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(); 
         } 
        } 
       }); 
      } 
     }; 
    }); 
関連する問題