【问题标题】:Angularjs ng-repeat doesn't update when the model changes模型更改时Angularjs ng-repeat不会更新
【发布时间】:2014-08-28 21:02:33
【问题描述】:

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

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

<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])

【问题讨论】:

  • 请不要忘记创建答案并标记它。所以人们不会花时间回答一个悬而未决的问题。 :)

标签: javascript angularjs angularjs-ng-repeat


【解决方案1】:

你需要申请的范围

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

这是一篇很好的博客文章,解释了它:

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

您的ng-repeat 在 $http 请求之后没有更新的原因是 $http 是异步的,并且您的控制器的 javascript 轮流在响应从您的 $http 请求返回之前完成。所以你必须通知作用域,事情发生了变化,并将其推送到作用域。

【讨论】:

  • 感谢您的回答。当我说的时候,浏览器会抛出一个错误:$digest already in progress :(
  • 我认为问题是 scope.watch ,应该是 scope.watchCollection,因为集合发生了变化,而不是推文引用。您不必调用 scope.$apply.
  • 我尝试使用 scope.watchCollection,但它做同样的事情
  • 非常感谢。你救了我。
  • 真正的英雄。节省了数小时的挫败感。谢谢你的朋友。
【解决方案2】:

问题在于检索数据的包装方式

而不是这个:

$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]);
        });

【讨论】:

    【解决方案3】:

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

    这是最简单的方法

    //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 承诺中。然后当它成功或错误时,然后履行承诺。中继器将兑现承诺。

    【讨论】:

      【解决方案4】:

      对于可能遇到 UI 未更新的此问题的任何其他人 - 即使在执行 $apply 或坚持 $timeout 之后也是如此。我刚刚意识到我犯了一个愚蠢的错误,并在嵌入属性中添加了 :: 并忘记了它。

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-06
        • 2023-03-17
        • 2013-07-03
        • 1970-01-01
        相关资源
        最近更新 更多