prevent重定向angularjs应用行为 [英] prevent redirect behaviour in angularjs app

查看:94
本文介绍了prevent重定向angularjs应用行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当用户尝试点击浏览器的后退按钮,并代雷是在表单上脏数据,它显示一个确认。

When a user tries to click browser back button and dere is dirty data on the form, it shows a confirmation.

下面是角JS控制器code

Here is the angular js controller code

   function MyCtrl2($rootScope, $location, $scope) {

    $rootScope.$watch(function () {
        return $location.path();
    },

    function (newValue, oldValue) {
        if ($scope.myForm.$dirty) {
            var a = confirm('do you');
            if (!a) {
                 //how to prevent this redirect
            }
        }
    },
    true);
}

MyCtrl2.$inject = ['$rootScope', '$location', '$scope'];

但如何prevent的重定向

But how to prevent the redirect on

推荐答案

有在你试图解决这整个问题的根源2 DOM事件:onhashchange和onbeforeunload。 onhashchange可以进行检查和prevented,但是,您的浏览器的后退按钮不会触发onhashchange。更糟的是,如果该页面没有加载,这意味着如果你打回转到页上previous哈希onbeforeunload不会触发,也不会触发。正因为如此,如果你preSS回走了previous航线它仍然会离开你的表单。

There are two DOM events at the root of this whole problem you're trying to solve: onhashchange and onbeforeunload. onhashchange can be checked and prevented, however, the Back button on your browser will not trigger onhashchange. What's worse, onbeforeunload will not trigger if the page doesn't reload, which means if you hit Back to go to a previous hash on the page, it will not fire. Because of this, if you press Back to to go a previous route it will still leave your form.

目前也href=\"https://github.com/angular/angular.js/issues/592\" rel=\"nofollow\">奥斯坦丁问题上角的待办事项列表如何

There is also currently an oustanding issue on Angular's todo list about how they're going to allow for the cancellation of a route. I'd presume the back button to a hash issue is what's hold them up at this point.

所以最后你可能要重新设计你的解决方案,如果你想prevent所有导航从表单远离一旦它被编辑做一些更激烈。就像一个标志存储所有形式在$ rootScope编辑的数据,以及表明它是肮脏的,但不完整的东西,然后添加一个事件处理程序routeChangeStart,检查这些值,并发送你回的形式。

So in the end you may want to re-engineer your solution to do something a little more drastic if you want to prevent all navigation away from your form once it's been edited. Something like storing all of the data the form is editing in $rootScope, along with a flag to show that it's dirty but incomplete, then add an event handler to routeChangeStart that checks those values and sends you back to the form.

下面是如何将工作(和 plunker如果你有兴趣):

Here's how that would work (and a plunker if you're interested):

app.config(function($routeProvider) {
  //set up the routes. (Important because we're going to navigate
  // BACK to them.)
  $routeProvider.when('/Form', {
    controller: 'FormCtrl',
    templateUrl: 'form.html'
  }).otherwise({
    controller: 'HomeCtrl',
    template: '<h3>Home</h3>' 
  });
});

app.run(function($rootScope, $location){ 
  //set up your rootScope formData object.
  $rootScope.formData = {};

  //add a routing event to check the route
  // and whether or not the data has been editted and then 
  // send it back to the proper form.
  $rootScope.$on('$routeChangeStart', function() {
    if($location.path() != '/Form' && $rootScope.formData.dirty && 
      !$rootScope.formData.complete && !confirm('Do you want to leave this form?')) {
      $location.path('/Form');
    }
  });

  //handle outright navigating away from the page.
  $(window).on('beforeunload', function() {
     if($rootScope.formData.dirty && 
      !$rootScope.formData.complete) {
         return 'Are you sure you want to navigate away from this form?';
     }
  });
});

app.controller('FormCtrl', function($scope) {
  $scope.$watch(function (){
    return $scope.myForm.$dirty;
  }, function(dirty) {
    $scope.formData.dirty = $scope.formData.dirty | dirty;
  })
});


其他的想法


other thoughts

起初我制定了一个指令来解决这个问题,但我意识到,这是行不通的,因为这些问题我在上面提到。无论如何,为后人的缘故,这里是:

Initially I had developed a directive to help with this, but I realized that it wouldn't work because of the issues I mentioned above. Regardless, for posterity's sake, here it is:

app.directive('form', function ($window){
  return {
    restrict: 'E',
    link: function(scope, elem, attrs) {

      //check for a prevent-if-dirty attribute on your form tag
      if(attrs.preventIfDirty !== undefined) {

        // first off, stop routing hash changes from 
        // changing the page.
        scope.$on('$locationChangeStart', function(event) {
          if(scope.testForm.$dirty) {
            event.preventDefault();
          }
        });

        // a little setup for our next piece
        var formName = attrs.name;
        function showWarning() {
          return 'You have changed the form';
        }

        // Now stop browser navigation from moving away
        // from your dirty form.
        scope.$watch(function (){
          return scope[formName].$dirty;
        }, function(dirty) {
          if(dirty) {
             $(window).on('beforeunload', showWarning);
          } else {
             $(window).off('beforeunload', showWarning);
          }
        });
      }
    }
  };
});

这里是一个展示plunker它。

这篇关于prevent重定向angularjs应用行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆