浏览器在 angularjs $http.get 崩溃

Browser crashes on angularjs $http.get

我正在使用 angularJs 开发模板系统,我正在使用来自外部 js 文件的 ng-include 将模板文件包含到我的视图中。

当我 运行 我的 index.html 浏览器时,它会在很长一段时间后崩溃。页面似乎不断地重新加载,我的 CPU 显示器爆棚了。

到底有什么错?我是 angularjs 的新手,所以如果有人能指出正确的方向,我将不胜感激。

index.html

<!DOCTYPE html>
<html lang="en" data-ng-app="angularTemplate" data-ng-controller="templateCtrl">
<head>
 <meta charset="UTF-8">
 <title>{{ pageName + " - " + siteName }}</title>

 <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>

</head>
<body>
  <header data-ng-include="includeHeader()"></header>
  <script type="text/javascript" src="./assets/js/templateCtrl.js"></script>
</body>
</html>

JS

var app = angular.module('angularTemplate', []);
app.controller('templateCtrl', function($scope, $http) {
  
  $scope.includeHeader = function(){
    $http.get("./assets/php/mysql.php?action=getSiteSetup")
    .success(function(response){
      $scope.siteName = response.siteName;
      $scope.siteTagline = response.siteTagline;
    });
    return "./assets/templates/header.html";
  }
  
});

mysql.php?action=getSiteSetup 是一个简单的 sql 调用,returns

{"siteName":"AngularJS Template","siteTagline":"Just another template...","siteBaseURL":"http:\/\/localhost\/angularjs_template\/"}

对于页面之间的路由,您应该使用 Angular-Route 或 ui.router。

此处举例说明:https://docs.angularjs.org/tutorial/step_07

这使用 ng-view 指令 允许您从您的网络应用程序中注入基于调用 url 的内容。 这里有 ng-view 文档:https://docs.angularjs.org/api/ngRoute/directive/ngView

真的很推荐你去看看,这样解决。这将彻底改造您的工作,但会让您在未来更轻松、更快地工作。而且它也会使对其进行测试变得更加容易。

另外请传递您的 header.html 代码以改进此答案。

由于以下两个实现而存在此问题:

<header data-ng-include="includeHeader()">

$scope.includeHeader = function(){
    $http.get("./assets/php/mysql.php?action=getSiteSetup")
    ...
}

您需要了解 AngularJS 的作用域如何检测作用域的变化。参见 here

基本上 AngularJS 将重复重新运行给定的表达式并将其与之前的值进行比较以确定其值是否已更改,如果已更改,那么它将根据范围变量更改执行所需的任何操作。因此 includeHeader() 每次 AngularJS 想要检查事情是否发生变化时都会重复重新运行。然而在你的 includeHeader 里面,它每次都会触发一个网络调用。为了使事情进入无限循环,AngularJS 决定是否需要检查范围更改的触发器之一是在 $http 完成时。这是你的无限循环。

简而言之,不要使用任何表达式来检查范围值是否是进程密集型,反之亦然。 includeHeader 不是您应该放置初始化代码的地方。只需在控制器中触发即可。

从控制器中 data-ng-include 指令绑定到的函数内部删除 Ajax 请求,这样代码如下所示

var app = angular.module('angularTemplate', []);
app.controller('templateCtrl', function($scope, $http) {
      $http.get("./assets/php/mysql.php?action=getSiteSetup")
        .success(function(response){
          $scope.siteName = response.siteName;
          $scope.siteTagline = response.siteTagline;
      });
      $scope.includeHeader = function(){
        return "./assets/templates/header.html";
      }
    });

注:

You don't necessary need to bind the ng-include directive to a
function on the scope when the template is not loaded dynamically based on user interactions