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