AngularJS $location 不改变路径

Posted

技术标签:

【中文标题】AngularJS $location 不改变路径【英文标题】:AngularJS $location not changing the path 【发布时间】:2012-07-31 20:22:33 【问题描述】:

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

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

    路由已设置,URL 被识别为某个表单页面。 页面加载、控制器设置变量、指令被触发。 触发了一个特殊的表单指令,该指令使用 AJAX 执行特殊的表单提交。 执行 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'];

有人可以帮帮我吗?

【问题讨论】:

Angular $location.path not working 的可能重复项 请记住,这是在那一年之前创建的。 对,另外一年的好处是,另一个人有一个更准确的正确答案。 @JimG。这不是重复的,这个问题是 4 年前的,你链接的问题是 2 年前的。 【参考方案1】:

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

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

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

【讨论】:

像魅力一样工作。我已将我使用的代码添加到您的帖子中以使其正常工作:) 非常感谢!!! 为了更好地了解 $apply 如何与 Angular 一起工作以及如何解决它的问题,这里有一个链接 yearofmoo.com/2012/10/… @Skeater 您可以简单地注入根范围并对其进行操作,如下所示: factory('xyz', ['$rootScope', function($rootScope) ...])跨度> 可以用 $timeout 包装你的回调,并且范围将被正确应用 就像 JasonS 说的,使用 $timeout(function() //apply changes here );这有两个优点: 1) 您不需要访问 $scope。 2)您不必担心 $apply 已经运行。出于第二个原因,使用 $timeout 通常是首选方法。【参考方案2】:

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

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

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

或者刷新一下,像这样:

$window.location.reload();

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

【讨论】:

我也是,当 url 有参数时 $location.path() 不会重定向 这是正确答案。见here【参考方案3】:

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

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

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

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

【讨论】:

不,这是个坏主意。只需检查阶段以防它在摘要中,然后您可以跳过应用。 Angular 会赶上它并自行更改 URL:coderwall.com/p/ngisma 超时对我来说似乎是一个肮脏的黑客行为。如果您的 href 包含“#”,则 $location.path() 不会按预期工作。只需完全删除 a 标签上的 href="#" 或设置为 href="",您就不需要使用 $timeout $$phase 是一个私有变量,您不应尝试访问它,因为它可能会在新的 angularjs 版本中发生变化。 使用 $timeout 可能是一个 hack,但使用 $$phase 是一个更大的 hack。一般来说,不要查看或触摸任何以 $$ 为前缀的东西。 经过大约 10 个小时的随机破坏......这个解决方案对我有用!【参考方案4】:

我必须像这样嵌入我的$location.path() 语句,因为我的摘要仍在运行:

       function routeMe(data)                 
            var waitForRender = function () 
                if ($http.pendingRequests.length > 0) 
                    $timeout(waitForRender);
                 else 
                    $location.path(data);
                
            ;
            $timeout(waitForRender);
        

【讨论】:

感谢功能,很有用! 对我来说,问题是我们使用了 angular-block-ui,它阻止了地址栏位置的更新。我们用 requestFilter 拾取的 bool 修饰了 $http 请求,这样 block-ui 就不会在该特定调用上触发,然后一切都很好。【参考方案5】:

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

例如:

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


$location.path('/abc');

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

【讨论】:

不是模板配置,而是路由配置。【参考方案6】:

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

【讨论】:

【参考方案7】:

这对我有用(在 CoffeeScript 中)

 $location.path '/url/path'
 $scope.$apply() if (!$scope.$$phase)

【讨论】:

【参考方案8】:

在我看来,这里的许多答案似乎有点老套(例如 $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

【讨论】:

【参考方案9】:
setTimeout(function()  $location.path("/abc"); ,0);

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

【讨论】:

运行非 setTimeout 是一个非常糟糕的主意。而且,正如@matsko 上面所说, $timeout 不是最好的主意。

以上是关于AngularJS $location 不改变路径的主要内容,如果未能解决你的问题,请参考以下文章

『AngularJS』$location 服务

[AngularJS] $location 服务简介

angularjs-$location

angularJS: $location 服务

angular 中怎么获取路径上的参数 参考:https://docs.angularjs.org/api/ng/service/$location

AngularJS如何修改URL中的参数