在 AngularJs 中调用 $routeChangeStart 之前显示确认模式,例如 window onbeforeunload

Show confirmation modal before calling $routeChangeStart in AngularJs like window onbeforeunload

一旦路线开始改变,我可以显示一个确认模式,如果用户选择保留我的路线没有改变,它会停留在原来的路线上,但会再次加载表单指令,这会导致表单丢失所有复选框,输入值。它被重置为默认值。

如果用户关闭页面,我可以显示确认模式,而且表单状态不会改变。保留所有值。

下面是我的代码: 另外,请注意,我还默认为所有路由注入解析(this Angular : How use one resolve for all the routes of my application

之后我打电话给 .run()

$rootScope.$on('$routeChangeStart', function (event, newUrl, oldUrl) {
            //isLoggedIn also check URL params
            if (!Auth.isLoggedIn()) {
                $window.location.href = Auth.getLoginUrl();
            }

            ////unsaved modal start
            if ($rootScope.unsaved) {

                ngDialog.open({
                    className: 'ngdialog-theme-default unsaved-modal',
                    template: 'scripts/core/commonmodal/tplUnsavedModal.html',
                    controller: [function OpenDialogContainer() {
                        var modal = this;
                        modal.message = 'You have some unsaved changes. Do you want to leave this page?';
                        modal.stop = function () {
                            modal.processing = true;
                            ngDialog.close();
                            $rootScope.$broadcast('$routeChangeSuccess');
                        };
                        modal.continue = function () {
                            modal.processing = true;
                            ngDialog.close();
                            $rootScope.unsaved = false;
                            $location.path(newUrl.$$route.originalPath); //Go to page they're interested in
                        };
                    }],
                    controllerAs: 'modal'
                });
                //prevent navigation by default since we'll handle it
                //once the user selects a dialog option
                event.preventDefault();
            }

        });

如果表单不是 $pristine 且不是 $submitted

,我将设置 $rootScope.unsaved = true

正如您在下面的 gif 视频中看到的,在停留期间,路线再次运行控制器功能。相反,我想要的是 window onbeforeunload 相似的效果。

http://recordit.co/g5T9wWkDry.gif

我只是通过删除这行 $rootScope.$broadcast('$routeChangeSuccess'); 来修复它,而不是我做了一个指令。

link: function($scope) {
                var message = 'You have some unsaved changes. Do you want to leave this page?';
                $window.onbeforeunload = function(){
                    if ($scope.unsavedChanges) {
                        return 'You have some unsaved changes. Do you want to leave this page?';
                    }
                };
                var $routeChangeStartUnbind = $rootScope.$on('$routeChangeStart', function(event, newUrl) {
                    if ($scope.unsavedChanges) {
                        $rootScope.pageloaded = true;//prevent loading icon
                        ngDialog.open({
                            appendClassName: 'unsaved-modal',
                            template: 'scripts/core/commonmodal/tplUnsavedModal.html',
                            controller: [function OpenDialogContainer() {
                                var modal = this;
                                modal.message = message;
                                modal.stop = function () {
                                    modal.processing = true;
                                    ngDialog.close();
                                };
                                modal.continue = function () {

                                    modal.processing = true;
                                    ngDialog.close();
                                    $routeChangeStartUnbind();
                                    $location.path(newUrl.$$route.originalPath); //Go to page they're interested in
                                    $rootScope.pageloaded = false;
                                    $scope.unsavedChanges = false;
                                    $window.location.reload();//$route.reload() does not reload services
                                };
                            }],
                            controllerAs: 'modal'
                        });
                        //prevent navigation by default since we'll handle it
                        //once the user selects a dialog option
                        event.preventDefault();
                    }
                });

                $scope.$on('$destroy', function() {
                    window.onbeforeunload = null;
                    $routeChangeStartUnbind();
                });
            }