功能:有一个页面,输入查询条件,点击查询按钮后从后台返回数据并显示在页面的表格中,并在页面滚动到最下面时实现下拉加载。
下拉加载什么的前面的博客已经讲过了,这里不再讲了,这里主要是记录bug问题,在从后台返回数据并成功加到数组后面了,但是页面上并没有渲染出来,好怀念vue.js的v-for啊啊啊啊啊,然后就去上网找填坑的方法,说是要用$scope.$apply();好像跟什么脏值检测有关,ok,我在本地写了一个简单的页面试试水
test.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.bootcss.com/angular.js/1.4.6/angular.min.js"></script>
</head>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<table border="1">
<tr ng-repeat="x in records track by $index">
<td>{{x.Name}}</td>
<td>{{x.Country}}</td>
</tr>
</table>
</div>
<script>
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope, $window) {
$scope.records = [{
"Name": "Alfreds Futterkiste",
"Country": "Germany"
}, {
"Name": "Berglunds snabbk",
"Country": "Sweden"
}, {
"Name": "Centro comercial Moctezuma",
"Country": "Mexico"
}, {
"Name": "Ernst Handel",
"Country": "Austria"
}, {
"Name": "Alfreds Futterkiste",
"Country": "Germany"
}, {
"Name": "Berglunds snabbk",
"Country": "Sweden"
}, {
"Name": "Centro comercial Moctezuma",
"Country": "Mexico"
}, {
"Name": "Ernst Handel",
"Country": "Austria"
}, {
"Name": "Alfreds Futterkiste",
"Country": "Germany"
}, {
"Name": "Berglunds snabbk",
"Country": "Sweden"
}, {
"Name": "Centro comercial Moctezuma",
"Country": "Mexico"
}, {
"Name": "Ernst Handel",
"Country": "Austria"
}, {
"Name": "Alfreds Futterkiste",
"Country": "Germany"
}, {
"Name": "Berglunds snabbk",
"Country": "Sweden"
}, {
"Name": "Centro comercial Moctezuma",
"Country": "Mexico"
}, {
"Name": "Ernst Handel",
"Country": "Austria"
}];
var tempData = [{
"Name": "1",
"Country": "test1"
}, {
"Name": "2",
"Country": "test2"
}, {
"Name": "3",
"Country": "test3"
}, {
"Name": "1",
"Country": "test1"
}, {
"Name": "2",
"Country": "test2"
}, {
"Name": "3",
"Country": "test3"
}, {
"Name": "1",
"Country": "test1"
}, {
"Name": "2",
"Country": "test2"
}, {
"Name": "3",
"Country": "test3"
}, {
"Name": "1",
"Country": "test1"
}, {
"Name": "2",
"Country": "test2"
}, {
"Name": "3",
"Country": "test3"
}, {
"Name": "1",
"Country": "test1"
}, {
"Name": "2",
"Country": "test2"
}, {
"Name": "3",
"Country": "test3"
}];
$window.onscroll = function() {
clients = $window.innerHeight || $window.document.documentElement.clientHeight || $window.document.body.clientHeight;
scrollTop = $window.document.documentElement.scrollTop;
wholeHeight = $window.document.documentElement.scrollHeight;
if (clients + scrollTop >= wholeHeight) {
console.log("我到底部了");
// 模拟异步请求数据
setTimeout(() => {
$scope.records.push(...tempData);
$scope.$apply(); // 这里一定要哦!!
}, 1000);
}
}
});
</script>
</body>
</html>
运行果然没问题,可以显示,看网上很多说是因为setTimeout或者用jquery的ajax等异步问题就会出现这种情况,因为angular本身存在脏值检测,但是由于你是异步,所以脏值检测已经过去了,所以页面才没有更新的,但是我不用setTimeout也非要用$scope.$apply()才能更新页面,更奇怪的是,如果我通过点击事件来改变时不需要$scope.$apply()就能及时更新,下拉加载就要。。。。什么鬼哦??
点击触发增加数据,完全不用$scope.$apply()
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.bootcss.com/angular.js/1.4.6/angular.min.js"></script>
</head>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<table border="1">
<tr ng-repeat="x in records track by $index">
<td>{{x.Name}}</td>
<td>{{x.Country}}</td>
</tr>
</table>
<button ng-click="loadMore()">点我</button>
</div>
<script>
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope, $window) {
$scope.records = [{
"Name": "Alfreds Futterkiste",
"Country": "Germany"
}, {
"Name": "Berglunds snabbk",
"Country": "Sweden"
}, {
"Name": "Centro comercial Moctezuma",
"Country": "Mexico"
}, {
"Name": "Ernst Handel",
"Country": "Austria"
}, {
"Name": "Alfreds Futterkiste",
"Country": "Germany"
}, {
"Name": "Berglunds snabbk",
"Country": "Sweden"
}, {
"Name": "Centro comercial Moctezuma",
"Country": "Mexico"
}, {
"Name": "Ernst Handel",
"Country": "Austria"
}, {
"Name": "Alfreds Futterkiste",
"Country": "Germany"
}, {
"Name": "Berglunds snabbk",
"Country": "Sweden"
}, {
"Name": "Centro comercial Moctezuma",
"Country": "Mexico"
}, {
"Name": "Ernst Handel",
"Country": "Austria"
}, {
"Name": "Alfreds Futterkiste",
"Country": "Germany"
}, {
"Name": "Berglunds snabbk",
"Country": "Sweden"
}, {
"Name": "Centro comercial Moctezuma",
"Country": "Mexico"
}, {
"Name": "Ernst Handel",
"Country": "Austria"
}];
var tempData = [{
"Name": "1",
"Country": "test1"
}, {
"Name": "2",
"Country": "test2"
}, {
"Name": "3",
"Country": "test3"
}, {
"Name": "1",
"Country": "test1"
}, {
"Name": "2",
"Country": "test2"
}, {
"Name": "3",
"Country": "test3"
}, {
"Name": "1",
"Country": "test1"
}, {
"Name": "2",
"Country": "test2"
}, {
"Name": "3",
"Country": "test3"
}, {
"Name": "1",
"Country": "test1"
}, {
"Name": "2",
"Country": "test2"
}, {
"Name": "3",
"Country": "test3"
}, {
"Name": "1",
"Country": "test1"
}, {
"Name": "2",
"Country": "test2"
}, {
"Name": "3",
"Country": "test3"
}];
$scope.loadMore = function() {
$scope.records.push(...tempData);
}
});
</script>
</body>
</html>
那我就用$scope.$apply()吧,项目打包运行报错[$rootScope:inprog] $digest already in progress......说我加了$scope.$apply(),,,所以我到底该不该加???
解决办法:加个判断,如果它已经在做脏值检测就不用你多此一举,Prevent error $digest already in progress when calling $scope.$apply()
if(!$scope.$$phase) {
//$digest or $apply
}