背景:私はフォームがダーティーな場合は停止ナビゲーションを作成しようとしています。私はSOに関するいくつかの質問/例を見てきましたが、やや機能的ですが、正しくはないものをまとめました。このディレクティブをWebアプリケーション全体の複数のフォームの属性として使用しようとしています。同一のディレクティブを使用する同じページ上の複数のフォームと、要素ディレクティブ内の1つのフォーム
問題:私は2つの<form>
要素(「Form1の」および「Form2の」)<tab>
要素内にネストされて含まれているページがあります。 Form2は、カスタム要素ディレクティブの内部にさらにネストされます。
フォームが汚れていて、別のページに移動しようとすると(UIルーターの変更)、私たちのプロンプトサービスから期待されるカスタムプロンプトが表示されます。しかし、私がページをリロードしようとすると、form2が汚れているときにのみ、ブラウザでプロンプトが表示されます。 form1が汚れている場合は、プロンプトは表示されません。
form1が汚れていて、リロードなどのウィンドウイベントが発生したときにブラウザのプロンプトを生成する方法を教えてもらえますか?
RELEVANT HTML
<!-- "main" view -->
<tabset>
<tab heading="Heading1">
<form name="FORM1" class="form-horizontal" form-dirty>
<!-- FORM STUFF -->
</form>
</tab>
<tab heading="Heading2">
<this-contains-form2 data="objOnScope"></this-contains-form2>
</tab>
</tabset>
<!-- "thisContainsForm2" template -->
<form name="FORM2" class="form-horizontal" form-dirty>
<!-- FORM STUFF -->
</form>
RELEVANT JAVASCRIPT
// "form-dirty" directive
angular.module('webapp.shared').directive('formDirty', ['$state', 'DlgPromptService', function($state, DlgPromptService) {
return {
scope: {theForm: '=name'},
restrict: 'A',
link: function (scope, element, attrs) {
scope.$watch('theForm', function() {
// if there's a UI router change
scope.$on('$stateChangeStart', function (event, toState, toParams){
// WHEN FORM1 DIRTY: PROMPT AND CONSOLE-LOG BOTH FORMS
// WHEN FORM2 DIRTY: PROMPT AND CONSOLE-LOG BOTH FORMS
console.log(scope.theForm);
// if form was not modified
if (!scope.theForm.$dirty) {
return;
}
else {
// if form was modified then intervene
// halt the route change
event.preventDefault();
// prompt user
DlgPromptService.confirm('Unsaved Changes',
'This form has unsaved changes.<br/>'
+'Are you sure you want to leave?')
.then(function() {
// we will proceed with the route change
scope.theForm.$setPristine();
$state.go(toState.name, toParams);
})
}
})
// if there's a window change (reload, etc)
window.onbeforeunload = function (event) {
// WHEN FORM1 DIRTY: NO PROMPT, NO CONSOLE LOG
// WHEN FORM2 DIRTY: PROMPT AND CONSOLE-LOG FORM2
console.log(scope.theForm);
// if form was not modified
if (!scope.theForm.$dirty) {
return;
}
else {
// prompt
return "prompt";
}
}
scope.$on('$destroy', function() {
window.onbeforeunload = undefined;
})
})
}
}
}])
// "thisContainsForm2" directive
angular.module('webapp.shared').directive('thisContainsForm2', function() {
var controller = function($scope, $http, $state, DlgPromptService) {
// CONTROLLER STUFF
}
return {
scope : {data: '='},
templateUrl : 'shared/thisContainsForm2.html',
controller : controller
}
})
ありがとうThomas、それは私の疑惑でもありました。それは複数のイベントリスナーについての良い提案ですが、私はそれについて検討します。 – Kevin