Angular:$http.get()只在opstate触发器上每秒触发一次

Angular: $http.get() only fires every second onpopstate trigger

本文关键字:一次 opstate http get Angular 只在 触发器      更新时间:2023-09-26

我有一个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()返回新数据
  • 第一个后退按钮事件
    • 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(),但在某些情况下,您不得不启动循环,尤其是使用异步回调。