表单不完整时如何取消路由更改或浏览器重新加载?

时间:2013-10-09 04:13:09

标签: angularjs

有以下情况:

  1. 浏览器重新加载,
  2. 结算标签
  3. 关闭浏览器
  4. 路线更改(例如点击链接)
  5. 点击浏览器后退按钮。或history.go(-1)。 MacBook上有3个手指轻扫。
  6. 如果用户填写了某种形式或处于写作中间,我们会想要阻止。

    我编写的这段代码工作正常,但如果我无法在多个文本字段中实现它,它绝对没用。目前它只检查我们是否在#/ write url。它没有检查任何输入。

    有什么方法可以解决这个问题?什么是检查目标文本字段的最佳方法。指令是解决方案吗? 类似的东西:

    <input type="text" warningOnLeave ng-model="title"/>
    

    <form warningOnLeave name="myForm">...</form>
    
    
     $rootScope.$on('$locationChangeStart', function(event, current, previous){
    
        console.log(current);
        console.log(previous);
        // Prevent route change behaviour
        if(previous == 'http://localhost/#/write' && current != previous){
            var answer = confirm ("You have not saved your text yet. Are you sure you want to leave?");
            if (!answer)
                event.preventDefault();     
        }
    
    });
    
    
    
    
    /** 
       Prevent browser behaviour
    */
    
    window.onbeforeunload = function (e) {
        if(document.URL == 'http://localhost/#/write'){
            e = e || window.event;
    
            // For IE and Firefox prior to version 4
            if (e) {
                e.returnValue = 'You have not saved your text yet.';
            }
    
            // For Safari
            return 'You have not saved your text yet.';
        }
        else
            return;
    }
    

1 个答案:

答案 0 :(得分:1)

Angular中的

Forms具有$dirty / $pristine属性,用于标记用户是否已与表单控件进行交互,以及随附的方法$setPristine()。我将基于此功能的所需功能。考虑:

<form name="theForm" ng-controller="TheCtrl" ...>

这将表单放在控制器的范围内,在给定的名称下。然后是:

controller("TheCtrl", function($scope, $rootScope) {
    $rootScope.$on('$locationChangeStart', function(event, current, previous) {
        if( $scope.theForm.$dirty ) {
            // here goes the warning logic
        }
    });
});

不要忘记在适当的时候(即提交或清除后)致电$scope.theForm.$setPristine()

对于窗口卸载情况,您必须观察$dirty标志。所以在之前的控制器中:

$scope.$watch("theForm.$dirty", function(newval) {
    window.myGlobalDirtyFlag = newval;
});

您必须执行此操作,因为window.onbeforeunload事件无权访问表单范围。然后,在您应用的全局部分:

window.onbeforeunload = function (e) {
    if( window.myGlobalDirtyFlag === true ) {
        // warning logic here
    }
};

同样,您可能希望在范围被销毁时清除全局脏标志,因此在控制器中:

$scope.$on("$destroy", function() {
    window.myGlobalDirtyFlag = false;
});