为什么 $scope.$apply 需要更新这个数组
Why is $scope.$apply necessary to update this array
我正在使用 Angular 1.5.9
和 angular-route 1.5.9
。我有一个可行的解决方案,但我需要 $scope.$apply()
才能更新 DOM.
对我来说没有意义
我正在使用工厂和控制器来更新在 ng-repeat
中使用的数组。我知道摘要循环没有被触发,这就是我需要使用 $scope.apply()
的原因,但我不明白为什么。这是失败的代码:
myApp.controller('MyGamesController', ['$http', '$firebaseAuth', 'DataFactory', '$scope', function ($http, $firebaseAuth, DataFactory, $scope) {
console.log('mygamescontroller running');
var self = this;
self.newGame = {}
self.games = [];
getGames();
function getGames() {
DataFactory.getGames().then(function (response) {
console.log('returned to controller from factory', response); // logs the correct response including lastest data, but DOM doesn't update
self.games = response; // self.games is correctly set, but not updated on the DOM
$scope.$apply(); // Updates the DOM
});
} //end getgames function
self.addGame = function () {
DataFactory.addGame(self.newGame).then(getGames);
}
}]); //end controller
Angular 路由器正在处理我的 controllerAs
,就像这样:
.when('/mygames' ,{
templateUrl: '/views/templates/mygames.html',
controller: 'MyGamesController',
controllerAs: 'mygames'
})
而 HTML 的 ng-repeat 部分的 HTML 看起来像这样:
<tbody>
<tr ng-repeat="game in mygames.games">
<td>{{game.game}}</td>
<td>{{game.number_players}}</td>
<td>{{game.time_to_play}}</td>
<td>{{game.expansion}}</td>
</tr>
</tbody>
顺便说一句,我确实尝试清除 self.games
数组并创建一个循环来推动每个数组,但这并没有解决问题。我仍然需要 $scope.$apply()
来更新 DOM.
如果有帮助,我有完整的回购协议(链接特定的提交):https://github.com/LukeSchlangen/solo_project/tree/df72ccc298524c5f5a7e63f4a0f9c303b395bafa
您可以像这样使用 routeProvider 在页面加载时获取游戏数组,而不是在您的控制器中获取游戏数组:
由于您的页面在加载时已经呈现(该数组为空),因此不会有任何事件触发摘要周期。
.when("/news", {
templateUrl: '/views/templates/mygames.html',
controller: 'MyGamesController',
controllerAs: 'mygames'
resolve: {
games: function(){
return DataFactory.getGames();
}
}
}
在你的控制器中:
app.controller("MyGamesController", function (games) {
var self = this;
self.newGame = {}
self.games = games;
});
Angular 不关注此处的更改,因为此代码的执行不在 Angular 的权限范围内。 Angular 监视承诺结果的最简单方法是使用 $q
库。
function getGames() {
return $q.resolve(DataFactory.getGames().then(function (response) {
self.games = response; // self.games is correctly set, but not updated on the DOM
}));
} //end getgames function
$q promises 由 Angular 管理,当 $q promise 解析时,它将期望 运行 摘要周期。
您还需要将 $q 包含并注入到您的控制器中。
myApp.controller('MyGamesController', ['$q', '$http', '$firebaseAuth', 'DataFactory', '$scope', function ($q, $http, $firebaseAuth, DataFactory, $scope) {
这篇优秀的 post 详细介绍了异步调用如何与摘要循环一起工作:
How do I use $scope.$watch and $scope.$apply in AngularJS?
我正在使用 Angular 1.5.9
和 angular-route 1.5.9
。我有一个可行的解决方案,但我需要 $scope.$apply()
才能更新 DOM.
我正在使用工厂和控制器来更新在 ng-repeat
中使用的数组。我知道摘要循环没有被触发,这就是我需要使用 $scope.apply()
的原因,但我不明白为什么。这是失败的代码:
myApp.controller('MyGamesController', ['$http', '$firebaseAuth', 'DataFactory', '$scope', function ($http, $firebaseAuth, DataFactory, $scope) {
console.log('mygamescontroller running');
var self = this;
self.newGame = {}
self.games = [];
getGames();
function getGames() {
DataFactory.getGames().then(function (response) {
console.log('returned to controller from factory', response); // logs the correct response including lastest data, but DOM doesn't update
self.games = response; // self.games is correctly set, but not updated on the DOM
$scope.$apply(); // Updates the DOM
});
} //end getgames function
self.addGame = function () {
DataFactory.addGame(self.newGame).then(getGames);
}
}]); //end controller
Angular 路由器正在处理我的 controllerAs
,就像这样:
.when('/mygames' ,{
templateUrl: '/views/templates/mygames.html',
controller: 'MyGamesController',
controllerAs: 'mygames'
})
而 HTML 的 ng-repeat 部分的 HTML 看起来像这样:
<tbody>
<tr ng-repeat="game in mygames.games">
<td>{{game.game}}</td>
<td>{{game.number_players}}</td>
<td>{{game.time_to_play}}</td>
<td>{{game.expansion}}</td>
</tr>
</tbody>
顺便说一句,我确实尝试清除 self.games
数组并创建一个循环来推动每个数组,但这并没有解决问题。我仍然需要 $scope.$apply()
来更新 DOM.
如果有帮助,我有完整的回购协议(链接特定的提交):https://github.com/LukeSchlangen/solo_project/tree/df72ccc298524c5f5a7e63f4a0f9c303b395bafa
您可以像这样使用 routeProvider 在页面加载时获取游戏数组,而不是在您的控制器中获取游戏数组:
由于您的页面在加载时已经呈现(该数组为空),因此不会有任何事件触发摘要周期。
.when("/news", {
templateUrl: '/views/templates/mygames.html',
controller: 'MyGamesController',
controllerAs: 'mygames'
resolve: {
games: function(){
return DataFactory.getGames();
}
}
}
在你的控制器中:
app.controller("MyGamesController", function (games) {
var self = this;
self.newGame = {}
self.games = games;
});
Angular 不关注此处的更改,因为此代码的执行不在 Angular 的权限范围内。 Angular 监视承诺结果的最简单方法是使用 $q
库。
function getGames() {
return $q.resolve(DataFactory.getGames().then(function (response) {
self.games = response; // self.games is correctly set, but not updated on the DOM
}));
} //end getgames function
$q promises 由 Angular 管理,当 $q promise 解析时,它将期望 运行 摘要周期。
您还需要将 $q 包含并注入到您的控制器中。
myApp.controller('MyGamesController', ['$q', '$http', '$firebaseAuth', 'DataFactory', '$scope', function ($q, $http, $firebaseAuth, DataFactory, $scope) {
这篇优秀的 post 详细介绍了异步调用如何与摘要循环一起工作: How do I use $scope.$watch and $scope.$apply in AngularJS?