javascript 当模型更改时,Angularjs ng-repeat 不会更新
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25557962/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Angularjs ng-repeat doesn't update when the model changes
提问by Charger513
I Have this code in my project. I try to add data from database using $http, but ng-repeat doesn't update de table, only shows a blank row.
我的项目中有这段代码。我尝试使用$http从数据库添加数据,但 ng-repeat 不更新表,只显示一个空行。
When I check the scope, data is already there. I've read many answers but they does not seem to be related to my problem.
当我检查范围时,数据已经存在。我已经阅读了很多答案,但它们似乎与我的问题无关。
<div ng-controller="TweetsController">
<table class="table table-striped table-bordered table-hover" width="100%">
<thead>
<tr>
<th class="col-md-5"><i class="fa fa-fw fa-twitter text-muted hidden-md hidden-sm hidden-xs"></i> Texto</th>
<th class="col-md-1 text-center"> Lista</th>
<th class="col-md-1 text-center"> Cuenta</th>
<th class="col-md-1 text-center"> Red</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="tuit in filtrado">
<td>{{tuit.texto}}</td>
<td class="text-center">{{tuit.lista.nombre}}</td>
<td class="text-center">{{tuit.lista.cuenta.nombre}}</td>
<td class="text-center">{{tuit.lista.cuenta.red.tipo}}</td>
</tr>
</tbody>
</table>
<div>
<pagination total-items="ufilter.length" itemsPerPage="itemsPerPage" ng-model="currentPage"></pagination>
</div>
</div>
Controller:
控制器:
.controller('TweetsController', ['$scope','$http','filterFilter', function($scope,$http,filterFilter) {
$scope.currentPage = 1;
$scope.itemsPerPage = 10;
$scope.filtrado = [];
$scope.setPage = function (pageNo) {
$scope.currentPage = pageNo;
};
// retrieve tweets
$http.get('admin/twitter').success(function(tweets) {
$scope.tweets = tweets;
});
$scope.saveTweet = function(isValid) {
if(isValid) {
var tuit = {
texto: $scope.texto,
lista_id: $scope.lista
};
$http.post('admin/twitter', tuit).success(function(t) {
$scope.tweets.push(t);
});
}
};
$scope.filtrar = function(filtro) {
if($scope.tweets != undefined) {
$scope.ufilter = filterFilter(filtro, $scope.buscar);
var inicio = ($scope.currentPage - 1) * $scope.itemsPerPage;
var fin = inicio + $scope.itemsPerPage;
$scope.filtrado = $scope.ufilter.slice(inicio, fin);
}
};
$scope.$watch('tweets', function() {
$scope.filtrar($scope.tweets);
});
$scope.$watch('currentPage', function() {
$scope.filtrar($scope.tweets);
});
$scope.$watch('buscar', function() {
$scope.filtrar($scope.tweets);
$scope.setPage(1);
});
}])
EDIT:
编辑:
I Solved it!
我解决了!
The problem is the way how the retrieve data is wrapped
问题是检索数据的包装方式
$scope.tweets.push(t[0])
采纳答案by Charger513
The problem is the way how the retrieve data is wrapped
问题是检索数据的包装方式
instead of this:
而不是这个:
$http.post('admin/twitter', tuit).success(function(t) {
$scope.tweets.push(t);
});
this:
这:
$http.post('admin/twitter', tuit).success(function(t) {
$scope.tweets.push(t[0]);
});
回答by Mohamed El Mahallawy
You need to apply to the scope
您需要申请的范围
$http.get('admin/twitter').success(function(tweets) {
$scope.tweets = tweets;
$scope.$apply()
});
This is a great blog post that explains it:
这是一篇很好的博客文章,解释了它:
http://jimhoskins.com/2012/12/17/angularjs-and-apply.html
http://jimhoskins.com/2012/12/17/angularjs-and-apply.html
The reason why your ng-repeat
is not updating after the $http request is due to the $http is async and your javascript turn for the controller has finished before the response is back from your $http request. So you must notify the scope that things have changed and push it to the scope.
您ng-repeat
在 $http 请求之后没有更新的原因是 $http 是异步的,并且在您的 $http 请求返回响应之前,您对控制器的 javascript 转换已经完成。所以你必须通知作用域发生了变化,并将其推送到作用域。
回答by Neil Palethorpe
For anyone else who may run into this issue where the UI just isn't updating - even after doing an $apply or sticking within a $timeout. I've just realised I made a stupid mistake and had added :: to the embedded property and forgotten about it.
对于可能遇到 UI 没有更新的这个问题的任何其他人 - 即使在执行 $apply 或坚持 $timeout 之后。我刚刚意识到我犯了一个愚蠢的错误,将 :: 添加到嵌入的属性并忘记了它。
So I had my ng-repeat and inside I had a {{ ::item.name }}
. For those of you who don't know what the :: does; it tells angular to set the data and not set any additional watches, which in turn then stops angular trying to update that property. This is useful for data that you know won't ever change. See the below link for more information on one time bindings:
http://blog.thoughtram.io/angularjs/2014/10/14/exploring-angular-1.3-one-time-bindings.html
所以我有我的 ng-repeat 并且在里面我有一个{{ ::item.name }}
. 对于那些不知道 :: 做什么的人;它告诉 angular 设置数据而不是设置任何额外的手表,这反过来又会停止 angular 尝试更新该属性。这对于您知道永远不会改变的数据很有用。有关一次性绑定的更多信息,请参阅以下链接:http:
//blog.thoughtram.io/angularjs/2014/10/14/exploring-angular-1.3-one-time-bindings.html
So my solution was just to remove the :: so: {{ ::item.name }}
became {{ item.name }}
所以我的解决方案只是删除 :: so:{{ ::item.name }}
成为{{ item.name }}
回答by Brian Webb
There is the easy way and the correct way.
有简单的方法和正确的方法。
This is the easy way
这是最简单的方法
//Utility Functions
function Digest($scope) {
//this may not be future proof, if it isn't then you may have to try $timeout(function(){//do something})
if (!$scope.$$phase) {
try {
//using digest over apply, because apply fires at root, and I generally don't need root.
$scope.$digest();
}
catch (e) { }
}
//console.log('$scope snapshot:', $scope);
}
In your code use this by calling
在您的代码中,通过调用使用它
$http.post('admin/twitter', tuit).success(function(t) {
Digest($scope.tweets.push(t));
});
This is the correct way.
这是正确的方法。
https://docs.angularjs.org/api/ng/service/$q
https://docs.angularjs.org/api/ng/service/$q
Have your HTTP call wrapped in a $q promise. Then when it is either succeed or error, then fulfill the promise. The repeater will honor the promise.
将您的 HTTP 调用包装在 $q 承诺中。然后当它成功或错误时,就兑现承诺。中继器将兑现承诺。