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 不改变路径的主要内容,如果未能解决你的问题,请参考以下文章
angular 中怎么获取路径上的参数 参考:https://docs.angularjs.org/api/ng/service/$location