我有一个表单,我想阻止用户导航而不将数据保存回服务器。我借用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);
}
瞧,这很有效。我有几个问题:
.$apply()
功能?我原以为代码会在$ rootScope的上下文中运行。$rootScope
吗?当表单的路由处于活动状态时,我只需要这个监听器。答案 0 :(得分:2)
首先,你的意思是$apply()
吗?其次,为什么要使用$rootScope
启动摘要周期而不是控制器内的$scope
。第三,我认为你没有使用正确的逻辑来实现所需的功能。事件$locationChangeStart
表示Angular应用程序中位置更改的开始。 $window.confirm()
会暂时停止该导航,而调用event.preventDefault()
将导致所有导航停止。因此,您应该等待$window.confirm()
的确认。如果使用点击取消,则proceed
将为false。如果proceed
为false,请致电event.preventDefault()
,否则请勿执行任何操作。当应用程序已经在导航到该页面的过程中,您无需致电$location.path()
。
我在这里创建了一个Plunk: