1.在模態框中控制返回的按鈕,點擊返回應該關閉模態框angularjs
// 設置審批頁面的歷史記錄,用於打開模態框點擊返回時關閉模態框 function setHistory() { modalInstance.dismiss("cancel"); window.removeEventListener("popstate", setHistory); } //模態窗口打開以後執行的函數 modalInstance.opened.then(function() { // 打開模態框須要關閉上一個返回按鈕監聽事件 if (typeof(_goBack) != "undefined") { window.removeEventListener("popstate", _goBack); } history.pushState(null, null, document.URL); window.addEventListener("popstate",setHistory, false); }); //點擊肯定回調函數 modalInstance.result.then(function (retValue) { window.removeEventListener("popstate", setHistory); if (angular.isFunction(callbackFunc)) { callbackFunc(); } }, function (reason) {//點擊取消回調函數 window.removeEventListener("popstate", setHistory); });
2.在基本信息頁面中不斷的切換tab,點擊返回按鈕,返回到列表頁web
function pushHistory() { history.pushState(null, null, document.URL); } function _goBack() { pushHistory(); window.location.href = document.referrer; } // 此部分代碼在angularjs的controller中編寫 // 延遲執行,避免頁面一打開就開始監聽 setTimeout(function() { pushHistory(); window.addEventListener("popstate", _goBack, false); },500); // 頁面銷燬事件 $scope.$on('$destroy', function() { window.removeEventListener("popstate", _goBack); });
總結: 1).在關閉頁面以後須要銷燬返回按鈕的監聽事件。 2).若是是打開模態框,在模態框打開的時候銷燬上一個頁面的監聽事件。 3).每個頁面都要知道上一個頁面的URL,且每個頁面都須要調用監聽函數。app
/** * 關於上面第三點的好的解決思路(共用$scope): * 在第一個頁面定義一個變量:$scope.canBack = true; * 打開彈窗時:$scope.canBack = false; * 在關閉彈窗或點返回按鈕時,會調用第一個頁面的監聽的返回按鈕的函數 * 若是$scope.canBack = true執行函數裏面的內容,不然賦值$scope.canBack = true */ $scope._goBack = function() { // 彈窗選擇以後會觸發 if ($scope._canBack) { // ... $scope.$apply(); } $scope._canBack = true; }
/** * 最好不要使用document.referrer,由於你從基本信息頁面切到列表頁的時候, * document.referrer記錄的是基本信息頁面的URL。 * 因此應該放須要跳轉的具體頁面的URL,這就須要本身手動構建好URL。 */ function _goBack() { pushHistory(); window.location.href = document.referrer; }
補充:
有一種case是:在模態框中在彈一個模態框,在第二個模態框中點擊返回按鈕時,兩個模態框都關閉了。正常的狀況下,應該是隻關閉第二個模態框。這涉及到了window.addEventListener的冒泡事件,試了一下下面這種狀況行不通。函數
function setHistory(e) { e = e || window.event; e.preventDefault(); e.stopPropagation(); modalInstance.dismiss("cancel"); window.removeEventListener("popstate", setHistory); }
解決方案是:定義一個全局的變量,標記當前在哪一個模態框。打開第二個模態框的時候修改變量,關閉第二個模態框的時候重置變量。在第一個模態框判判定義的變量的值。code
var propagationFlag = 0; // 第一個模態框 function setHistory() { if (propagationFlag === 0) { modalInstance.dismiss("cancel"); window.removeEventListener("popstate", setHistory); } } // 第二個模態框 function setHistory() { propagationFlag = 0; modalInstance.dismiss("cancel"); window.removeEventListener("popstate", setHistory); } // 打開第二個模態框時 function openTwoModal() { propagationFlag = 1; } // 關閉第二個模態框時 function closeTwoModal() { propagationFlag = 0; }
如何共用$scope?其實也就封裝成dialog成一個module就好了。大概的思路就這樣,擼直就能夠的了。事件
(function() { 'use strict'; var dialogModule = angular.module('app.dialog', []).factory('Dialog', AngularDialog); function AngularDialog($modal, $rootScope, $http, $timeout) { return function($scope) { var dialog = { showDialog: function(args1, okCallbackFunc, cancelCallbackFunc, isAutoBackOnePage){ var resolve = { args1: function () { return args1; } }; var modalInstance = $modal.open({ templateUrl: $rootScope.webContext + args1.templateUrl, controller: args1.ctrlName, resolve: resolve, size : 'lg', }); function setHistory() { dialogPropagationFlag.approvalStages = 0; modalInstance.dismiss("cancel"); window.removeEventListener("popstate", setHistory, false); } //模態窗口打開以後執行的函數 modalInstance.opened.then(function() { // 用於上一個頁面也有監聽按鈕的狀況,_canBack爲true的時候才觸發第一個頁面的返回按鈕事件 $scope._canBack = false; history.pushState(null, null, document.URL); window.addEventListener("popstate", setHistory, false); }); //點擊肯定回調函數 modalInstance.result.then(function (retValue) { dialogPropagationFlag.approvalStages = 0; window.removeEventListener("popstate", setHistory, false); if (okCallbackFunc) { if (isEmptyString(isAutoBackOnePage) || isAutoBackOnePage) { window.history.go(-1); // 歷史記錄回退一層 } okCallbackFunc(retValue); } }, function (reason) {//點擊取消回調函數 dialogPropagationFlag.approvalStages = 0; window.removeEventListener("popstate", setHistory, false); if (cancelCallbackFunc) { cancelCallbackFunc(reason); } }); } } return dialog; } } })();