在HTML上我有一个叠加div来显示使用指令ng-show="showLoading"
的加载进度。在模板ng-click
上,我调用控制器searchRequest
方法。在发出http请求之前,此方法会将showLoading
更新为true。
如果我这样做,加载不会显示,如果我使用$scope.$apply
更新变量,那么我收到$apply already in progress
错误消息。到底是怎么回事?我该怎么做?
这是index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
<link href="css/ionic.app.css" rel="stylesheet">
-->
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<script src="js/angular-route.js" ></script>
<!-- your app's js -->
<script src="js/searchController.js"></script>
<script src="js/app.js"></script>
</head>
<body ng-app="myApp" ng-init="showLoading = false">
<div id="overlay" ng-show="showLoading">
<img id="loading" src="img/ajax-spinner.gif" />
</div>
<div ng-view></div>
</body>
</html>
模板:
<div ng-controller="searchController as searchController">
<ion-header-bar class="bar-stable">
<h1 class="title">Movie Searcher</h1>
</ion-header-bar>
<ion-content>
<label class="item item-input">
<span class="input-label">Title</span>
<input style="border-style: solid;border-width: 1px;" type="text" ng-model="searchController.searchString" required>
</label>
<button class="btn" ng-click="searchController.search()">Search</button>
{{response}}
</ion-content>
</div>
控制器:
this.searchRequest = function(url) {
$scope.showLoading = true;
$http.get(url).success(function(data) {
$scope.showLoading = false;
//console.log("Success: " + JSON.stringify(data));
$scope.response = JSON.stringify(data);
for (i=0; i<data.length; i++) {
var movie = data[i];
//console.log("Movie: " + movie);
var genres = '';
for (j=0; j<movie.genres.length; j++) {
genres += movie.genres[j];
if (j < movie.genres.length - 1) {
genres += ', ';
}
}
console.log("Title: " + movie.title);
console.log("Plot: " + movie.simplePlot);
console.log("genres: " + genres);
}
})
.error(function(data, status, headers, config) {
$scope.showLoading = false;
$scope.response = "Error: " + status;
})};
答案 0 :(得分:4)
您的Overlay div没有右侧控制器的数据上下文。
当您指定ng-controller指令时,您正在告诉angular使用该特定控制器作为其当前范围。
<div ng-controller="searchController as searchController">
然而,对于您的身体部分,您没有指定正确的控制器。因此,angular并不知道showloading属性的来源。
<body ng-app="myApp" ng-init="showLoading = false">
<div id="overlay" ng-show="showLoading">
<img id="loading" src="img/ajax-spinner.gif" />
</div>
<div ng-view></div>
</body>
将overlay div移动到将控制器作为上下文的div中,或者尝试使用$ rootScope。
答案 1 :(得分:0)
强制摘要周期而不必担心阶段的最简单方法可能是将var change调用包装在$ timeout函数中:
$timeout(function() {
$scope.showLoading = true;
}, 0);
$http.get(url).success(function(data) {
...
当然,不要忘记在控制器中注入$ timeout作为依赖项。