129

我在提交表单后更改页面的 URL 时遇到问题。

这是我的应用程序的流程:

  1. 路由已设置,URL 被某些表单页面识别。
  2. 页面加载,控制器设置变量,指令被触发。
  3. 触发一个特殊的表单指令,该指令使用 AJAX 执行特殊的表单提交。
  4. 在执行 AJAX 之后(Angular 不处理 AJAX)然后触发回调并且指令调用$scope.onAfterSubmit设置位置的函数。

问题是在设置位置后什么都没有发生。我也尝试将位置参数设置/为......不。我也试过不提交表格。没有任何效果。

我已经测试过代码是否到达了onAfterSubmit函数(确实如此)。

我唯一的想法是函数的范围以某种方式改变了(因为它是从指令中调用的),但是onAfterSubmit如果范围改变了它又怎么能调用呢?

这是我的代码

var Ctrl = function($scope, $location, $http) {
  $http.get('/resources/' + $params.id + '/edit.json').success(function(data) {
    $scope.resource = data;
  });

  $scope.onAfterSubmit = function() {
    $location.path('/').replace();
  };
}
Ctrl.$inject = ['$scope','$location','$http'];

有人可以帮帮我吗?

4

9 回答 9

303

几天前我遇到了类似的问题。在我的情况下,问题是我使用 3rd 方库(准确地说是 jQuery)改变了一些东西,在这种情况下,即使调用函数和设置变量工作 Angular 并不总是认识到有变化,因此它永远不会消化。

$apply() 用于从 Angular 框架外部执行 Angular 表达式。(例如来自浏览器 DOM 事件、setTimeout、XHR 或第三方库)。

尝试$scope.$apply()在更改位置后立即使用并调用replace()以让 Angular 知道事情发生了变化。

于 2012-08-13T10:16:47.920 回答
56

$location.path(...)我没有更改或刷新页面,而是使用了服务$window。在 Angular 中,此服务用作对象的接口window,并且该window对象包含一个属性location,使您能够处理与位置或 URL 内容相关的操作。

例如,window.location您可以分配一个新页面,如下所示:

$window.location.assign('/');

或者刷新它,像这样:

$window.location.reload();

它对我有用。它与您的预期略有不同,但适用于给定的目标。

于 2015-01-27T14:25:49.927 回答
28

我遇到了同样的问题,但我对 $location 的调用已经在摘要中。调用 $apply() 只是给出了一个 $digest already in process 错误。

这个技巧有效(并确保注入$location您的控制器):

$timeout(function(){ 
   $location...
},1);

虽然不知道为什么这是必要的......

于 2014-04-03T16:03:57.767 回答
6

我不得不$location.path()像这样嵌入我的声明,因为我的摘要仍在运行:

       function routeMe(data) {                
            var waitForRender = function () {
                if ($http.pendingRequests.length > 0) {
                    $timeout(waitForRender);
                } else {
                    $location.path(data);
                }
            };
            $timeout(waitForRender);
        }
于 2015-08-07T19:21:03.733 回答
2

就我而言,问题是我的模板配置中缺少可选参数指示符('?')。

例如:

.when('/abc/:id?', {
    templateUrl: 'views/abc.html',
    controller: 'abcControl'
})


$location.path('/abc');

如果没有询问字符,路由显然不会改变抑制路由参数。

于 2015-09-12T19:54:53.590 回答
1

如果你们中的任何人使用 Angular-ui / ui-router,请使用:$state.go('yourstate')而不是$location. 它对我有用。

于 2016-07-26T19:40:23.423 回答
0

这对我有用(在 CoffeeScript 中)

 $location.path '/url/path'
 $scope.$apply() if (!$scope.$$phase)
于 2017-01-16T02:42:52.897 回答
0

在我看来,这里的许多答案似乎有点老套(例如 $apply() 或 $timeout),因为搞乱 $apply() 会导致不必要的错误。

通常,当 $location 不起作用时,这意味着某些东西没有以角度方式实现。

在这个特定的问题中,问题似乎出在非角度 AJAX 部分。我有一个类似的问题,使用 $location 的重定向应该在承诺解决后进行。我想说明这个例子的问题。

旧代码:

taskService.createTask(data).then(function(code){
            $location.path("task/" + code);
        }, function(error){});

注意:taskService.createTask 返回一个承诺。

$q - 使用 Promise 的角度方式:

let dataPromises = [taskService.createTask(data)];
        $q.all(dataPromises).then(function(response) {
                let code = response[0];
                $location.path("task/" + code);
            }, 
            function(error){});

使用 $q 来解决 promise 解决了重定向问题。

有关 $q 服务的更多信息:https ://docs.angularjs.org/api/ng/service/ $q

于 2020-03-30T10:27:00.820 回答
-8
setTimeout(function() { $location.path("/abc"); },0);

它应该可以解决您的问题。

于 2014-08-30T19:58:12.923 回答