我有一个AngularJS应用程序,它调用API并返回一组数据,然后用户可以通过标签过滤这些数据,以获得更大的结果粒度。每次点击标签过滤数据时,应用程序都会进行新的$http.get()
调用,并使用适当的查询参数修改URL,以便用户可以保存永久链接并返回任何特定的数据集。
我试图用window.history.pushState()
为应用程序提供适当的历史处理,并将每个历史对象的相关查询参数作为状态数据传递。我使用window.onpopstate
来检测何时单击后退/前进按钮,并使用历史中的相关状态数据进行新的$http.get()
调用。
出于某种原因,$http.get()
函数只在每秒popstate
时触发,然后它进行两次调用。这几乎就像有一些缓存在进行,但我还没能找到罪魁祸首。这种行为在前后两个方向上都持续存在,并且持续存在于每一秒的事件中。我已经验证了window.history.length
对于每个添加/删除的标记只增加1,状态数据正在成功发送,新的搜索查询正在正确组装,并且请求路径是正确的。只是没有开火。发生了什么事??
举例来说,行为流程如下所示:
- 在
/default
加载页面- 添加第一个标签:URL为
/default&tags=a
,$http.get()
返回新数据 - 添加第二个标签:URL为
/default&tags=a,b
,$http.get()
返回新数据 - 添加第三个标签:URL为
/default&tags=a,b,c
,$http.get()
返回新数据 - 添加第四个标签:URL为
/default&tags=a,b,c,d
,$http.get()
返回新数据
- 添加第一个标签:URL为
- 第一个后退按钮事件
window.onpopstate
触发,URL现在为/default&tags=a,b,c
- 没有网络更改
- 第二个后退按钮事件
window.onpopstate
触发,URL现在为/default&tags=a,b
$http.get()
触发,用/default&tags=a,b,c
发送网络数据请求$http.get()
再次触发,用/default&tags=a,b
发送网络数据请求/default&tags=a,b
负载的数据集
- 第三个后退按钮事件
window.onpopstate
触发,URL现在为/default&tags=a
- 没有网络更改
- 第四个后退按钮事件
window.onpopstate
触发,URL现在为/default
$http.get()
触发,用/default&tags=a
发送网络数据请求$http.get()
再次触发,用/default
发送网络数据请求/default
负载的数据集
相关代码片段:
$scope.apiRequest = function(options, callback) {
// Omitted: a bunch of functions to build query
// based on user-selected tags.
// I've verified that this is working correctly.
$http.get(path)
.then(function(response) {
console.log('http request submitted');
if (callback) {
callback(response.data.response, response.data.count, response.data.facets);
console.log('data returned');
}
}, function(response) {
console.log('there has been an error');
});
}
成功和错误事件都不会触发。我试过使用$http.get().then().catch()
来查看是否有其他事情发生,但由于某种原因,我在控制台中不断收到一个错误,说...catch()
不是一个有效的函数,这本身就令人困惑。有什么想法吗?
谢谢!
这听起来表明函数没有在$digest
循环中循环。在这种情况下,您可以尝试将$scope.$apply();
添加为window.onpopstate
处理程序函数的最后一行,以启动$digest
循环来执行函数调用。
这篇文章,Notes On AngularJS Scope Life Cycle,帮助我更好地理解了$digest
循环,以及如何强制使用$scope.$apply();
运行$digest
循环。请记住,您希望谨慎使用$scope.$apply()
,但在某些情况下,您不得不启动循环,尤其是使用异步回调。