4

我有一个 AngularJS 应用程序,它调用 API 并返回一堆数据,然后用户可以按标签过滤这些数据,以便在结果中获得更大的粒度。每次单击标签以过滤数据时,应用程序都会进行新的$http.get()调用,并使用适当的查询参数修改 URL,以便用户可以保存永久链接并返回到任何特定的数据集。

我正在尝试为应用程序提供适当的历史处理window.history.pushState(),并将每个历史对象的相关查询参数作为状态数据传递。我window.onpopstate用来检测何时单击后退/前进按钮,并使用它来使用$http.get()历史记录中的相关状态数据进行新调用。

出于某种原因,该函数仅每秒$http.get()触发一次,然后进行两次调用。几乎好像有一些缓存正在进行,但我一直无法找到罪魁祸首。这种行为在两个方向上持续存在,向后和向前,并且每隔一个事件就持续一次。我已经验证,对于添加/删除的每个标签,它只增加 1,状态数据正在成功发送,新的搜索查询正在正确组装,并且请求路径是正确的。只是没有开火。这是怎么回事?? popstatewindow.history.length

为了说明,行为流如下所示:

  • 加载页面在/default
    • 添加第一个标签: URL is /default&tags=a$http.get()返回新数据
    • 添加第二个标签: URL is /default&tags=a,b$http.get()返回新数据
    • 添加第三个标签: URL is /default&tags=a,b,c$http.get()返回新数据
    • 添加第四个标签: URL is /default&tags=a,b,c,d$http.get()返回新数据
  • 第一个后退按钮事件
    • 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()不是一个有效的功能,这本身就令人困惑。有任何想法吗?

谢谢!

4

1 回答 1

2

这听起来表明一个函数没有在循环中$digest循环。在这种情况下,您可以尝试添加$scope.$apply();作为处理程序函数中的最后一行window.onpopstate以启动$digest循环以执行您的函数调用。

这篇文章,关于 AngularJS 范围生命周期的注释帮助我更好地理解$digest循环以及如何强制$digest循环运行$scope.$apply();请记住,您希望$scope.$apply()谨慎使用,但在某些情况下,您被迫开始循环,尤其是使用异步回调。

于 2015-08-28T19:46:54.170 回答