53

我是一個新的角色js。我試圖編寫一個驗證,當他試圖關閉瀏覽器窗口時提醒用戶。當用戶離開頁面時顯示在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上。 任何關於如何實現這一點的指針,將不勝感激。

我得到了一個答案here,但它在每個時間間隔後彈出消息。

更新後的代碼;

控制器

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 = []; 
+11

我相信你想要的術語是 「[新手](http://www.urbandictionary.com/define.php?term=newbie)」。除非你真的是一隻意大利蜜蜂。 – 2015-12-15 16:22:27

回答

100

代碼Ë確認對話框可以寫成短這樣​​:

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

這是一個更清潔的解決方案。另一個導致我導航無限循環確認... – wakandan 2014-04-03 04:24:35

+1

還有一個標準JavaScript事件處理程序,它監聽資源卸載。即當它不是一個SPA應用程序。監聽器可以分配給'window.onbeforeunload'。 – Eugene 2015-03-02 08:45:57

+5

不幸的是,當你使用路由服務時,這是行不通的,每當位置發生變化時觸發事件。 – user544262772 2015-05-20 09:11:12

41

讓獨立你的問題,你問的是兩種不同的東西:

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; 
} 

而對於第二個問題,做這種方式:

你應該以掛鉤處理$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(); 
     } 
    }); 
} 
+0

我想要一個提醒,通知用戶他即將離開該頁面,他真的想繼續嗎?希望我很清楚。 – iJade 2013-02-11 12:09:14

+0

@jade請看我更新的答案。 – 2013-02-11 12:24:01

+0

我應該在哪裏放這個代碼。不過,我是一個完整的angularjs新bie? – iJade 2013-02-11 12:24:47

9

正如你上面發現了,你可以使用的window.onbeforeunload$locationChangeStart組合來消息的用戶。另外,您可以利用ngForm.$dirty僅在用戶進行更改時向用戶發送消息。

我已經編寫了一個angularjs指令,您可以將其應用於任何可以自動監視更改並在用戶重新加載頁面或導航時自動發送消息的窗體。 @see https://github.com/facultymatt/angular-unsavedChanges

希望您覺得這個指令很有用!

19

這是我使用的指令。當表單被卸載時它會自動清理自己。如果您想阻止提示(例如,因爲您成功保存了表單),請調用$ 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(); 
       } 
      }); 
     } 
    }; 
}]); 
+2

我不得不在FF中使用'$(window).bind('beforeunload',doPrompt);'而不是'window.addEventListener('beforeunload',areYouSurePrompt);'(和'unbind'' removeEventListener') 31.0出於任何原因,原生'window'調用不工作(而'window.onbeforeunload = function(){return「sure?」;}'工作)?!另外從我可以告訴,'$ locationChangeStart'永遠不會開火,並考慮使用'onbeforeunload'這個塊真的有必要嗎? – Campbeln 2014-08-27 01:49:05

+0

@Campbeln upvoted的提示,上面的代碼也沒有在Chrome42上工作,我不得不如你所說的做。 – 2015-04-24 03:38:04

2

其他的例子做工精細的老版本用戶界面路由器(> = 0.3.X),但所有國家的活動,如$stateChangeStart,是deprecated as of 1.0。新的UI路由器1.0代碼使用$transitions service。因此,您需要將$transitions注入您的組件,然後使用$transitions.onBefore方法,如下面的代碼所示。

 
$transitions.onBefore({}, function(transition) { 
    return confirm("Are you sure you want to leave this page?"); 
}); 

這只是一個超級簡單的例子。 $transitions服務可以接受更復雜的響應,如承諾。有關更多信息,請參閱HookResult type

-1
$scope.rtGo = function(){ 
      $window.sessionStorage.removeItem('message'); 
      $window.sessionStorage.removeItem('status'); 
     } 

$scope.init = function() { 
      $window.sessionStorage.removeItem('message'); 
      $window.sessionStorage.removeItem('status'); 
     }; 

刷新頁面:在使用init

相關問題