当模型发生变化时,Angularjs ng-repeat不会更新

时间:2014-08-28 21:02:33

标签: javascript angularjs angularjs-ng-repeat

我在我的项目中有这个代码。我尝试使用 $ http 从数据库添加数据,但ng-repeat没有更新de table,只显示一个空行。

当我检查范围时,数据已经存在。 我已经阅读了很多答案,但它们似乎与我的问题无关。

<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('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);
    });     

}])

编辑:

我解决了!

问题在于如何包装检索数据

$scope.tweets.push(t[0])

4 个答案:

答案 0 :(得分:9)

您需要申请范围

 $http.get('admin/twitter').success(function(tweets) {
        $scope.tweets = tweets;
        $scope.$apply()
});

这是一篇很棒的博文,解释了它:

http://jimhoskins.com/2012/12/17/angularjs-and-apply.html

$ http请求后$ ng-repeat未更新的原因是$ http是异步的,并且在响应从$ http请求返回之前,控制器的javascript转为已完成。因此,您必须通知范围已发生变化并将其推送到范围。

答案 1 :(得分:3)

问题在于如何包装检索数据

而不是:

$http.post('admin/twitter', tuit).success(function(t) {
            $scope.tweets.push(t);
        });

这样:

$http.post('admin/twitter', tuit).success(function(t) {
            $scope.tweets.push(t[0]);
        });

答案 2 :(得分:0)

有简单的方法和正确的方法。

这是一种简单的方法

//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);
}

在您的代码中,通过调用

来使用它
        $http.post('admin/twitter', tuit).success(function(t) {
           Digest($scope.tweets.push(t));
        });

这是正确的方法。

https://docs.angularjs.org/api/ng/service/$q

将您的HTTP调用包含在$ q承诺中。然后当它成功或错误时,履行承诺。转发器将兑现承诺。

答案 3 :(得分:0)

对于任何可能遇到此问题的用户,即使在$ timeout或$ timeout内进行更新后,用户也无法进行更新。我刚刚意识到我犯了一个愚蠢的错误并将::添加到了嵌入式属性并忘记了它。

所以我有了ng-repeat而且里面有{{ ::item.name }}。对于那些不知道::做什么的人;它告诉angular设置数据而不设置任何额外的手表,然后停止角度试图更新该属性。这对于您知道不会发生变化的数据非常有用。有关一次性绑定的更多信息,请参阅以下链接: http://blog.thoughtram.io/angularjs/2014/10/14/exploring-angular-1.3-one-time-bindings.html

所以我的解决方案就是删除:: so:{{ ::item.name }}成为{{ item.name }}