我正在使用#!/OrderList?id=123
这样的链接,它会显示所有订单的列表以及订单123的更多详细信息。使用reloadOnSearch=false
并观看$routeUpdate
它可以正常工作,但只有一个事情:所有这些链接都被放入浏览器历史记录中,而我更喜欢只有一个这样的链接。例如,而不是
#!/OrderList?id=123
#!/OrderList?id=124
#!/OrderList?id=125
#!/AnotherList?id=678
#!/AnotherList?id=679
每个组的最后一个成员,即
#!/OrderList?id=125
#!/AnotherList?id=679
我知道$location.replace()
,但是当通过跟随链接进行更改时,我看不到将它放在哪里。我试图将它放在$scope.$on("$routeUpdate", ...)
中,但它没有做任何事情,可能是因为路线已经改变时为时已晚。
我既不使用router-ui
也不使用HTML5模式(只是简单angular-route
)。
我很害怕,我不清楚我坚持使用href
而不是自定义处理程序。我希望链接能够与鼠标中键和书签以及所有内容一起使用。 ng-href
和ng-click
的组合可以做我想要的,但我发现simple solution使用普通链接。
答案 0 :(得分:3)
看起来您可能想要使用ng-click功能更新URL查询参数而不是依赖链接,然后调用类似下面的函数来更新参数...使用替换状态,历史记录应该只跟踪当前值。我没有测试过这个案例,所以如果你试试,请告诉我它是否有效。
function changeUrlParam (param, value) {
var currentURL = window.location.href;
var urlObject = currentURL.split('?');
var newQueryString = '?';
value = encodeURIComponent(value);
if(urlObject.length > 1){
var queries = urlObject[1].split('&');
var updatedExistingParam = false;
for (i = 0; i < queries.length; i++){
var queryItem = queries[i].split('=');
if(queryItem.length > 1){
if(queryItem[0] == param){
newQueryString += queryItem[0] + '=' + value + '&';
updatedExistingParam = true;
}else{
newQueryString += queryItem[0] + '=' + queryItem[1] + '&';
}
}
}
if(!updatedExistingParam){
newQueryString += param + '=' + value + '&';
}
}else{
newQueryString += param + '=' + value + '&';
}
window.history.replaceState('', '', urlObject[0] + newQueryString.slice(0, -1));
}
答案 1 :(得分:2)
也许您可以做的是,而不是常规<a ng-href="#!/OrderList?id={{your.id}}">Link to your ID</a>
您可以创建一个带有ng-click
指令的链接,该指令绑定到一个函数,该函数检索数据并将其传递给视图。
`<span ng-click="loadListItem(your.id)">Link to your ID</span>`
<div id="your-item-data">
{{item.id}} - {{item.name}}
</div>
myApp.controller('someController', function($scope) {
$scope.loadListItem(itemId) = function (
var myItem;
// Get item by 'itemId' and assign it to 'myItem' var
$scope.item = myItem;
);
});
这样您就可以检索控制器中的项目数据并将其传递给您的视图,而不是更改您的网址。
您没有提供有关控制器/服务实施的详细信息,但我希望这会有所帮助。
答案 2 :(得分:2)
我认为你跟$scope.$on("$routeUpdate", ...)
事情走在了正确的轨道上。但是,不是$routeUpdate
,而是尝试绑定$routeChangeStart
:
$scope.$on("$routeChangeStart", function(event, nextRoute, currentRoute){
if (nextRoute.yourCriteria === currentRoute.yourCriteria){
//do your location replacement magic
}
});
如果需要,您甚至可以在路径定义中定义dontUpdateHistory
布尔属性,然后在run
块中检查该属性:
myApp.config(function($routeProvider){
$routeProvider.when('/whatever' {
templateUrl: 'whatever',
dontUpdateHistory: true //something like this
});
}).run(function($rootScope){
$rootScope.on('$routeChangeStart', function(event, nextRoute, currentRoute){
if (nextRoute.dontUpdateHistory){
//do your location replacement magic
}
});
我还没有测试过这一点,但希望它可以解决这个问题。
答案 3 :(得分:0)
我对任何答案都不满意,经过一些调试后我发现了这个解决方案:
.run(function($rootScope, $location) {
var replacing;
$rootScope.$on("$locationChangeStart", function(event, newUrl, oldUrl) {
if (oldUrl === newUrl) return; // Nobody cares.
// Make urls relative.
var baseLength = $location.absUrl().length - $location.url().length;
newUrl = newUrl.substring(baseLength);
oldUrl = oldUrl.substring(baseLength);
// Strip search, leave path only.
var newPath = newUrl.replace(/\?.*/, "");
var oldPath = oldUrl.replace(/\?.*/, "");
// Substantial change, history should be written normally.
if (oldPath !== newPath) return;
// We're replacing, just let it happen.
if (replacing) {
replacing = false;
return;
}
// We're NOT replacing, scratch it ...
event.preventDefault();
// ... and do the same transition with replace later.
$rootScope.$evalAsync(function() {
$location.url(newUrl).replace();
replacing = true;
});
});
})