javascript 在没有无限摘要的情况下从 Angular 成功调用 history.pushState()?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22914228/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Successfully Call history.pushState() from Angular Without Inifinite Digest?
提问by Blaskovicz
Is there a way to call history.pushState()
without angular going into an infinite digest loop?
有没有办法在history.pushState()
没有角度进入无限摘要循环的情况下进行调用?
I'm trying to migrate my app from backend routing to frontend routing and all the stackoverflow posts/google resources don't seem to have an answer.
我正在尝试将我的应用程序从后端路由迁移到前端路由,并且所有 stackoverflow 帖子/谷歌资源似乎都没有答案。
回答by Torsten Uhlmann
This is what we do in an Angular 1.2.16 app based on this github comment: https://github.com/angular/angular.js/issues/3924#issuecomment-48592773
这是我们在基于此 github 评论的 Angular 1.2.16 应用程序中所做的:https: //github.com/angular/angular.js/issues/3924#issuecomment-48592773
$location.url(myNewUrl);
$location.replace();
$window.history.pushState(null, 'any', $location.absUrl());
This code is part of a controller. I'm using it to add a query param to the url without wanting to reload the page. It works in our case.
此代码是控制器的一部分。我正在使用它向 url 添加查询参数,而不想重新加载页面。它适用于我们的情况。
回答by Daniel Bonnell
I recently encountered a variation of this problem myself and none of the answers here worked for me in isolation. history.pushState
was defined, but only worked if called from the console. I was able to come up with a solution by consolidating a few of the answers here. Here is the code I used to solve this problem:
我最近自己遇到了这个问题的一个变体,这里没有一个答案单独对我有用。history.pushState
已定义,但仅在从控制台调用时才有效。我能够通过在此处合并一些答案来提出解决方案。这是我用来解决这个问题的代码:
// Configure $locationProvider html5Mode
app.config(['$locationProvider', function($locationProvider) {
$locationProvider.html5Mode({ enabled: true, requireBase: false, rewriteLinks: false });
}]);
// In controller
$window.history.pushState(null, 'Page Title', '/some_new_url');
I'm running Angular 1.5.5.
我正在运行 Angular 1.5.5。
回答by clint
Use the rewriteLinks option on the $locationProvider html5Mode object:
在 $locationProvider html5Mode 对象上使用 rewriteLinks 选项:
pageModule.config(function($locationProvider) {
$locationProvider.html5Mode({
enabled: true,
requireBase: false,
rewriteLinks: false
});
});
Afterwards, you should be able to use the $location service properly, such as:
之后,您应该可以正常使用 $location 服务,例如:
this.$location.path("/mynewpath");
回答by Blaskovicz
I was able to come up with a solution that works with angular 1.2.15.
我能够想出一个适用于 angular 1.2.15 的解决方案。
The gist of it is to add a target
attribute to each link and then use the $location
service to change the location.
它的要点是为target
每个链接添加一个属性,然后使用该$location
服务更改位置。
Based on the current angular code, anchor tags that have a target attribute are ignored (note that this solution may eventually break).
根据当前的 angular 代码,具有 target 属性的锚标记将被忽略(请注意,此解决方案最终可能会中断)。
To do this, ensure this javascript runs beforeangular:
为此,请确保此 javascript在angular之前运行:
// prevent angular from taking over link clicks until we have frontend routing
$(document.documentElement).on("click","a",function(event) {
var elem = $(this), target = elem.attr("target");
if(!target) {
elem.attr("target","_self");
setTimeout(function() {
elem.removeAttr("target");
});
}
});
After that, configure your location provider to use html5mode:
之后,将您的位置提供程序配置为使用 html5mode:
angular.module("App", ["App.controllers"]).config([
"$locationProvider", function($locationProvider) {
if (history.pushState) {
$locationProvider.html5Mode(true);
}
}
]);
Now, in your controller, inject the location service and use it normally:
现在,在您的控制器中,注入定位服务并正常使用它:
angular.module("App.controllers",[]).controllers("SomeController", ["$scope", "$location", function($scope,$location){
$scope.updateLocation = function() {
if (history.pushState) {
$location.path("/new/path/here");
}
};
}]);