web-dev-qa-db-ja.com

ユーザーがページを離れたときに、angularjsでアラートを表示する

私はangularjsの新しいミツバチです。ユーザーがブラウザーウィンドウを閉じようとしたときに警告する検証を作成しようとしています。

ページv1とv2に2つのリンクがあります。リンクをクリックすると、特定のページに移動します。 v1およびv2にリダイレクトするコードは次のとおりです

angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives'])

.config(['$routeProvider', function($routeProvider) {
        $routeProvider.when('/v1', {templateUrl: 'pages/v_1.html', controller: MyCtrl1});
        $routeProvider.when('/v2', {templateUrl: 'pages/v_2.html', controller: MyCtrl2});
        $routeProvider.otherwise({redirectTo: '/v1'});
}]);

ユーザーがv1をクリックすると、「続行したい場合はv1から離れようとしています」というメッセージをポップアップし、v2をクリックしても同じメッセージを表示したい。これを達成する方法についてのポインタをいただければ幸いです。

答えが得られました ここ ですが、毎時間ごとにメッセージがポップアップされます。

更新コード;

コントローラー

function MyCtrl1() {
    $scope.$on('$locationChangeStart', function (event, next, current) {
        if ('your condition') {
            event.preventDefault();

            MessageService.showConfirmation(
                'Are you sure?',
            MessageService.MessageOptions.YES_NO, {
                'YES': function () {
                    blockNavigation = false;
                    $location.url($location.url(next).hash());
                    $rootScope.$apply();
                },
                'NO': function () {
                    MessageService.clear();
                    $log.log('NO Selected')
                }
            });
        }
    });
}
MyCtrl1.$inject = [];


function MyCtrl2() {}
MyCtrl2.$inject = [];
58
iJade

確認ダイアログのコードは、このように短く書くことができます。

$scope.$on('$locationChangeStart', function( event ) {
    var answer = confirm("Are you sure you want to leave this page?")
    if (!answer) {
        event.preventDefault();
    }
});
105
Scheintod

あなたの質問を分けましょう、あなたは2つの異なることについて尋ねています:

1。

ユーザーがブラウザーウィンドウを閉じようとしたときに警告する検証を作成しようとしています。

2。

ユーザーがv1をクリックすると、「続行したい場合はv1から離れようとしています」というメッセージをポップアップし、v2をクリックしても同じメッセージを表示したい。

最初の質問については、次のようにします。

window.onbeforeunload = function (event) {
  var message = 'Sure you want to leave?';
  if (typeof event == 'undefined') {
    event = window.event;
  }
  if (event) {
    event.returnValue = message;
  }
  return message;
}

2番目の質問では、次のようにします。

$locationChangeStartイベントを処理して遷移イベントを表示するためにフックする必要があります。そのため、このコードを使用してコントローラーで遷移検証を処理します。

function MyCtrl1($scope) {
    $scope.$on('$locationChangeStart', function(event) {
        var answer = confirm("Are you sure you want to leave this page?")
        if (!answer) {
            event.preventDefault();
        }
    });
}
43
Yair Nevet

これが私が使用するディレクティブです。フォームがアンロードされると、自動的にクリーンアップされます。 (たとえば、フォームを正常に保存したために)プロンプトが起動しないようにしたい場合は、$ scope.FORMNAME。$ setPristine()を呼び出します。ここで、FORMNAMEはプロンプトを禁止したいフォームの名前です。

.directive('dirtyTracking', [function () {
    return {
        restrict: 'A',
        link: function ($scope, $element, $attrs) {
            function isDirty() {
                var formObj = $scope[$element.attr('name')];
                return formObj && formObj.$pristine === false;
            }

            function areYouSurePrompt() {
                if (isDirty()) {
                    return 'You have unsaved changes. Are you sure you want to leave this page?';
                }
            }

            window.addEventListener('beforeunload', areYouSurePrompt);

            $element.bind("$destroy", function () {
                window.removeEventListener('beforeunload', areYouSurePrompt);
            });

            $scope.$on('$locationChangeStart', function (event) {
                var Prompt = areYouSurePrompt();
                if (!event.defaultPrevented && Prompt && !confirm(Prompt)) {
                    event.preventDefault();
                }
            });
        }
    };
}]);
22

上記で発見したように、window.onbeforeunload$locationChangeStartの組み合わせを使用してユーザーにメッセージを送ることができます。さらに、ngForm.$dirtyを利用して、ユーザーが変更を加えたときにのみユーザーにメッセージを送ることができます。

Angularjsディレクティブを作成しました。このディレクティブは、変更を自動的に監視し、ユーザーがページをリロードしたり別の場所に移動した場合にユーザーにメッセージを送信する任意のフォームに適用できます。 @see https://github.com/facultymatt/angular-unsavedChanges

このディレクティブが役立つことを願っています!

9
facultymatt

ここにある他の例は、旧バージョンのui-router(> = 0.3.x)で正常に機能しますが、$stateChangeStartなどのすべての状態イベントは 1.0で非推奨 です。新しいui-router 1.0コードは $ transitions service を使用します。そのため、コンポーネントに$transitionsを注入し、以下のコードが示すように $ transitions.onBefore メソッドを使用する必要があります。

 $ transitions.onBefore({}、function(transition){
 return confirm( "このページから移動しますか?"); 
}); 

これは非常に単純な例です。 $transitionsサービスは、promiseなどのより複雑な応答を受け入れることができます。詳細については、 HookResult type を参照してください。

2
Brent Matzelle