1

HTML

<tr ng-repeat="client in (filteredItems = (clients | filter:searchText | orderBy:sortingOrder:reverse))">
          ....

Controller:

function SomeController($scope,$http) {
    $http.get("http://www.example.com/someapi", function(data) {
        $scope.clients = data; // This code will cause a digest.
        waitUtilDigestEnd()  // I want to block it until the digest ends up so that $scope.filteredItems is up to date. How to write this code?
        handle($scope.filteredItems)
    })
}
function handle(filteredItems) {
   .....
}

My question is how to re-calculate filteredItems variable to make filteredItems contains newest data.

Raymond
  • 19
  • 3
  • It's not clear what your issue is. Calculate what? What is `handleFilteredData`? – charlietfl Jul 17 '14 at 04:32
  • once you get new value from service assign to clients and use $scope.$apply() it will rebind your data again – Francis Stalin Jul 17 '14 at 05:29
  • you can see clients is from ajax data, and filteredItems = (clients | filter:searchText | orderBy:sortingOrder:reverse) in template. – Raymond Jul 17 '14 at 06:29
  • The problem really is that you assign `filteredItems` in the view. Don't do this, and the solution becomes apparent. – Yoshi Jul 17 '14 at 08:08

2 Answers2

0

Since loadAjax()'s callback runs asynchronously, it will execute outside of the Angular context, meaning Angular will not know something changed.

In order for Angular to be aware of the changes, you should wrap your code in $scope.$apply():

loadAjax('...', function (data) {
    $scope.$apply(function () {
        $scope.data = data;
        ...
    });
});

UPDATE:

If you want to call handleFilteredData() after the rest of the tasks have been completed, you can wrap it in $evalAsync():

loadAjax('...', function (data) {
    $scope.data = data;
    ...
    $scope.$evalAsync(function () {
        handleFilteredData($scope.filteredItems);
    });
});

This approach doesn't seem to make much sense though, since filteredItems will change whenever the search-query or the sorting order changes and handleFilteredData() is not called for those cases. So, why do you want to handle filteredItems and not just handle data (unfiltered) ?

gkalpak
  • 47,844
  • 8
  • 105
  • 118
  • In fact, I use $http in function loadAjax, so angular knows the data is changed. after code $scope.clients = data; the digest begins to run, I need to know when the digest is finished so that we can run handleFilteredData($scope.filteredItems) – Raymond Jul 17 '14 at 06:21
  • Because I want to export filtered data. – Raymond Jul 18 '14 at 02:09
  • @Raymond: And what happens when the user changes the search query (and the filtered data changes) ? – gkalpak Jul 18 '14 at 06:35
0

I find the solution at AngularJS : Prevent error $digest already in progress when calling $scope.$apply()

$timeout(function() {
    // anything you want can go here and will safely be run on the next digest.
    handle($scope.filteredItems)
})  
Community
  • 1
  • 1
Raymond
  • 19
  • 3