AngularJS路由取消 - 为什么我需要使用$ rootScope?

时间:2014-04-16 20:47:05

标签: javascript angularjs url-routing

我有一个表单,我想阻止用户导航而不将数据保存回服务器。我借用here中的代码,让我为$locationChangeStart事件添加一个监听器。我在控制器中为我的表单添加了以下代码,并且看,没有任何反应。

    var cancelRouteListener = $rootScope.$on('$locationChangeStart', checkForUnsavedData);

    function checkForUnsavedData (event, newURL) {
        if (!$scope.form.$dirty) {
            return;
        }

        var proceed = $window.confirm('The page has unsaved changes. Do you want to continue?');

        if (proceed) {
            cancelRouteListener();
            $location.path(newURL);
        }

        event.preventDefault();
        return;
    }

我可以看到代码到达$location.path()的调用,但页面导航没有改变。然后,我出于绝望,尝试在调用$rootScope.$apply()时包裹该行代码:

$rootScope.$apply(function () {
    $location.path(newURL);
}

瞧,这很有效。我有几个问题:

  1. 为什么我需要使用.$apply()功能?我原以为代码会在$ rootScope的上下文中运行。
  2. 我真的需要将此附加到$rootScope吗?当表单的路由处于活动状态时,我只需要这个监听器。

1 个答案:

答案 0 :(得分:2)

首先,你的意思是$apply()吗?其次,为什么要使用$rootScope启动摘要周期而不是控制器内的$scope。第三,我认为你没有使用正确的逻辑来实现所需的功能。事件$locationChangeStart表示Angular应用程序中位置更改的开始。 $window.confirm()会暂时停止该导航,而调用event.preventDefault()将导致所有导航停止。因此,您应该等待$window.confirm()的确认。如果使用点击取消,则proceed将为false。如果proceed为false,请致电event.preventDefault(),否则请勿执行任何操作。当应用程序已经在导航到该页面的过程中,您无需致电$location.path()

我在这里创建了一个Plunk:

http://plnkr.co/edit/qfRVDtIlKqQ1p0pZ4oZ1?p=preview