动态加载页面时AngularJS的ng-repeat指令无法正常工作
问题分析与解决方案
你遇到的核心问题是动态加载的Angular内容未被正确初始化和编译,主要有两个原因:
- 页面中存在多个
ng-app:Angular只会自动初始化第一个检测到的ng-app,后续的ng-app不会被识别。 - jQuery AJAX插入的DOM未经过Angular编译:Angular初始化完成后,新插入的DOM里的指令(比如
ng-repeat)不会自动生效。
下面是具体的解决步骤:
步骤1:统一Angular模块,移除多余的ng-app
修改AJAX加载页面的代码,复用主页面的myapp模块,不要新建独立的myapplist模块:
<script> // 复用主页面已定义的myapp模块,无需重新创建 angular.module('myapp').controller('listCtrl', function($scope) { $scope.list = <? echo json_encode($myarr3); ?>; }); </script> <!-- 移除ng-app属性,主页面已有全局的ng-app --> <div ng-controller="listCtrl" id="list-container"> <div ng-repeat="i in list">{{i.isim}}</div> </div>
步骤2:手动编译动态插入的DOM
jQuery的html()方法插入内容后,Angular无法感知新DOM的存在,需要手动调用$compile服务编译这些内容。修改你的AJAX请求代码:
$('.subcate-class').click(function(){ var thissub = $(this).text(); var thiscate = $(this).parent('.subcate-holder').prev('.cate-class').text(); // 获取主页面的Angular作用域 var mainScope = angular.element('#cate-container').scope(); $.ajax({ url:"php/salelist.php", data:{kategori:thiscate,altkategori:thissub}, type:'POST', success: function(e){ var $listHolder = $('#list-holder'); $listHolder.html(e); // 编译新插入的DOM,让Angular识别其中的指令 angular.element($listHolder).injector().invoke(function($compile) { var targetScope = angular.element($listHolder).scope() || mainScope; $compile($listHolder.contents())(targetScope); // 触发Angular的脏检查,更新视图 targetScope.$apply(); }); } }); });
更优方案:改用Angular原生$http请求(推荐)
如果可以的话,尽量使用Angular自身的$http服务处理请求,这样更符合Angular的工作流,无需手动处理编译:
- 修改主页面的子分类点击事件,改用Angular的
ng-click:
<div ng-repeat="y in subcategory | filter:{kategori:x.isim}" class="subcate-class" ng-click="loadList(x.isim, y.isim)"> {{y.isim}} </div>
- 在主页面的
categoryCtrl中添加加载列表的方法:
angular.module('myapp', []).controller('categoryCtrl', function($scope, $http, $compile) { $scope.category = <? echo json_encode($myarr); ?>; $scope.subcategory = <? echo json_encode($myarr2); ?>; $scope.loadList = function(cate, subcate) { $http.post("php/salelist.php", {kategori: cate, altkategori: subcate}) .then(function(response) { var $listHolder = angular.element('#list-holder'); $listHolder.html(response.data); // 编译并绑定作用域 $compile($listHolder.contents())($scope); }); }; });
关键注意事项
- 一个页面中只能保留一个
ng-app,Angular会自动初始化第一个,多个ng-app会导致后续模块无法生效。 - 动态插入的DOM必须经过
$compile处理,Angular才能识别其中的指令(如ng-repeat、ng-controller)。 - 如果使用jQuery的AJAX,需要手动调用
$apply()触发Angular的脏检查;使用Angular的$http则无需额外处理,因为$http会自动触发脏检查。
内容的提问来源于stack exchange,提问作者Güney Saramalı
相关产品推荐
相关产品推荐

