AngularJS:更新数组后,ng-repeat不刷新

时间:2016-06-20 15:10:17

标签: javascript angularjs ionic-framework angularjs-ng-repeat

我正在使用Ionic框架,并尝试使用以下HTML代码显示“Card”元素列表:

<div ng-repeat="case in cases">

    <div class="list card">

      <div class="item item-avatar">
        <button ng-click="rmpost(card.key)" style="background: transparent; border: none;"><i class="icon ion-close-round"></i></button><!--if (dataSnapshot.val().volunteer_email == firebase.auth().currentUser.email)-->
        <h2>{{card.volunteer_name}} ({{card.volunteer_email}})</h2>
        <p>{{card.title}} ({{card.creationdate}})</p>
      </div>

      <div class="item item-body">
        <img class="full-image" src={{card.snapshot}}>
        <p>{{card.message}}</p>
      </div>

    </div>

      </div>

这是我在控制器中使用的JS代码,用于更新案例数组:

.controller('campaignslookCtrl', function($rootScope, $scope, $cordovaGeolocation, $state, $ionicPopup, Util)
        {
            $scope.reload = function()
            {
            $scope.reload();
            }

            $scope.rmpost = function(key)
            {
              alert("rmpost");
            }

            $scope.cases = [];

            //...

    firebase.database().ref('/cases')
        .on('child_added', function(dataSnapshot)
            {

            $scope.cases.push({key: dataSnapshot.key,
                                     volunteer_name: dataSnapshot.val().volunteer_name,
                                     volunteer_email: dataSnapshot.val().volunteer_email,
                                     title: dataSnapshot.val().title,
                                     creationdate: '',//(new Date(dataSnapshot.val().creationdate)).toString(),
                                     snapshot: dataSnapshot.val().snapshot,
                                     message: dataSnapshot.val().message});

});
//..
})

$ scope.cases在初始化为常量值时得到很好的显示,但在动态更新时(通过$ push)没有显示任何内容。

3 个答案:

答案 0 :(得分:2)

您需要使用push方法打包$apply来电。因为您是从角度范围外部(来自firebase回调)添加到数组项目中。

尝试以下方法:

...
firebase.database().ref('/cases')
        .on('child_added', function(dataSnapshot)
            {
                $scope.$apply(function () {
                    $scope.cases.push({key: dataSnapshot.key,
                                     volunteer_name: dataSnapshot.val().volunteer_name,
                                     volunteer_email: dataSnapshot.val().volunteer_email,
                                     title: dataSnapshot.val().title,
                                     creationdate: '',//(new Date(dataSnapshot.val().creationdate)).toString(),
                                     snapshot: dataSnapshot.val().snapshot,
                                     message: dataSnapshot.val().message});

                 });
             });
...

答案 1 :(得分:1)

与MaKCbIMKo相同的答案。

我想补充一点,这是一个更容易阅读的选择:

pip install baseapi

答案 2 :(得分:1)

问题是您在角度上下文之外更新模型。数据已经更改,但有角度没有运行它自己的内部摘要,也没有意识到您的模型中发生了任何更改。

firebase.database().ref('/cases')
        .on('child_added', function(dataSnapshot) //FIREBASE EVENT NOT WITHIN ANGULAR CONTEXT

您需要使用有角度的$scope.$apply方法。

https://docs.angularjs.org/api/ng/type/ $ rootScope.Scope#$应用

  

$申请([曝光]); $ apply()用于以角度执行表达式   从角框架的外部。 (例如来自浏览器DOM   events,setTimeout,XHR或第三方库)。 因为我们   调用角度框架我们需要执行适当的范围   异常处理的生命周期,执行手表。

以下是如何使用$scope.$apply进入有效的角度上下文然后更新数据:

firebase.database().ref('/cases')
        .on('child_added', function(dataSnapshot)
            {
                $scope.$apply(function() {
                    //we are now within the angular context, so any updates to the model with be handled correctly
                    $scope.cases.push({key: dataSnapshot.key,
                                     volunteer_name: dataSnapshot.val().volunteer_name,
                                     volunteer_email: dataSnapshot.val().volunteer_email,
                                     title: dataSnapshot.val().title,
                                     creationdate: '',//(new Date(dataSnapshot.val().creationdate)).toString(),
                                     snapshot: dataSnapshot.val().snapshot,
                                     message: dataSnapshot.val().message});
                });
});

理论上你可以手动调用$scope.$digest,但这不是'#1}。根据角度文档推荐。 $apply正确转发异常,并允许处理观察者。使用此方法通常比自己处理$digest更好。

  

$消化();处理当前范围的所有观察者及其   儿童。因为观察者的听众可以改变模型,所以   $ digest()一直呼叫观察者,直到不再有听众为止   射击。这意味着可以进入无限循环。   此函数将抛出超过最大迭代限制。&#39;如果   迭代次数超过10次。

     

通常,您不会直接在控制器或中调用$ digest()   的指令。相反,你应该调用$ apply()(通常来自)   指令),它将强制$ digest()。