これが私の問題です。2つのビュー(View1とView2)と、各ビューのコントローラー(Ctrl1とCtrl2)があります。 View1では、ユーザーが誤って変更を保存せずにページを離れる前に、ユーザーに警告しようとしています。
私は問題なく動作するwindow.onbeforeunloadを使用していますが、私の問題は、1つのコントローラーでのみonbeforeunloadを持っているにもかかわらず、イベントが2番目のコントローラーでもトリガーされるように見えることです!しかし、私はそこにそのイベントさえ持っていません。ユーザーがページを離れて保存されていない変更がある場合、ユーザーがアラートを閉じてページを離れると、ユーザーは2番目のビューに戻りますか、ユーザーがこの別のビューを離れようとすると、onbeforeunloadによって警告されます。また、未保存の変更についても警告を受けます!そうでないときも!なぜこうなった?
また、$ locationChangeStartを使用していますが、これは正常に機能しますが、ユーザーがブラウザーを更新するとき、「戻る」を押すとき、または閉じようとするときではなく、ユーザーがルートを変更したときにのみ、onbeforeunload(より良いアプローチがあれば、教えてください)。どんな助けやより良いアプローチも大歓迎です!
//In this controller I check for window.onbeforeunload
app.controller("Ctrl1", function ($scope, ...)){
window.onbeforeunload = function (event) {
//Check if there was any change, if no changes, then simply let the user leave
if(!$scope.form.$dirty){
return;
}
var message = 'If you leave this page you are going to lose all unsaved changes, are you sure you want to leave?';
if (typeof event == 'undefined') {
event = window.event;
}
if (event) {
event.returnValue = message;
}
return message;
}
//This works only when user changes routes, not when user refreshes the browsers, goes to previous page or try to close the browser
$scope.$on('$locationChangeStart', function( event ) {
if (!$scope.form.$dirty) return;
var answer = confirm('If you leave this page you are going to lose all unsaved changes, are you sure you want to leave?')
if (!answer) {
event.preventDefault();
}
});
}
//This other controller has no window.onbeforeunload, yet the event is triggered here too!
app.controller("Ctrl2", function ($scope, ...)){
//Other cool stuff ...
}
私はonlocationunloadをトリガーしたいビューにいるときにのみユーザーに警告するために$ location.path()で現在のパスをチェックしようとしましたが、これは他のonbeforeunloadを実行しないことですコントローラー。
私は$ location.path()を追加しました!= '/ view1'最初に動作しているようですが、私には正しくないようですが、2つのビューしか持っていないので、いくつかのビューがあり、これはより多くのコントローラーが関与することでトリッキーになります:
app.controller("Ctrl1", function ($scope, ...)){
window.onbeforeunload = function (event) {
//Check if there was any change, if no changes, then simply let the user leave
if($location.path() != '/view1' || !$scope.form.$dirty){
return;
}
var message = 'If you leave this page you are going to lose all unsaved changes, are you sure you want to leave?';
if (typeof event == 'undefined') {
event = window.event;
}
if (event) {
event.returnValue = message;
}
return message;
}
//This works only when user changes routes, not when user refreshes the browsers, goes to previous page or try to close the browser
$scope.$on('$locationChangeStart', function( event ) {
if (!$scope.form.$dirty) return;
var answer = confirm('If you leave this page you are going to lose all unsaved changes, are you sure you want to leave?')
if (!answer) {
event.preventDefault();
}
});
}
それを定義したコントローラーが範囲外になったら、onbeforeunloadイベントを登録解除します。
$scope.$on('$destroy', function() {
delete window.onbeforeunload;
});
上記の解決策を試みたところ、それはうまくいきませんでした。手動で入力する場合でもdelete window.onbeforeunload
は、コンソールで関数を削除しません。代わりに、プロパティを未定義に設定する必要がありました。
$scope.$on('$destroy', function(e){
$window.onbeforeunload = undefined;
});
angular-ui-router を使用している場合は、$stateChangeStart
の代わりに $locationChangeStart
、例:.
$scope.$on('$stateChangeStart', function (event){
if (forbit){
event.preventDefault()
}
else{
return
}
})
これの更新として、angular-ui-routerを使用する人のために、$ transitionsをコントローラーに渡して使用します。
$transitions.onStart({}, function ($transition)
{
$transition.abort();
//return false;
});