Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I guess the title is pretty much clear what I am asking. I have created this fiddle : http://jsfiddle.net/Sourabh_/HB7LU/13142/

In the fiddle I have tried to replicate an async scenario. This is just an example but in an AJAX call if I don't use $scope.$apply() the list does not get updated. I want to know if it is safe to use $scope.$apply() every time I make an AJAX call to update a list or is there some other mechanism I can make use of?

Code I have written to replicate the scenario(same as in fiddle):

HTML

<div ng-controller="MyCtrl">
  <li ng-repeat="item in items">
    {{item.name}}
  </li>
  <button ng-click="change()">Change</button>
</div>

JS

var myApp = angular.module('myApp',[]);

function MyCtrl($scope) {
  $scope.items = [{name : "abc"},{name : "xyz"},{name : "cde"}];

  $scope.change = function(){
    test(function(testItem){
      $scope.items = testItem;
      //$scope.$apply();
    })
  }
  function test(callback){
    var testItem = [
                    {name : "mno"},
                    {name : "pqr"},
                    {name :   "ste"}
                   ];
    setTimeout(function(){callback(testItem)},2000);
  }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
247 views
Welcome To Ask or Share your Answers For Others

1 Answer

Edit It was not clear the OP was trying to mock a backend call. Even so, using the $timeout service is a great way to avoid the need of calling $scope.$apply manually and is a more generally applicable solution than using a Promise (in cases where you're i.e. not calling $http it doesn't always make sense to force your changes into the next cycle by wrapping them with a Promise).


Update your code to use the $timeout service and it should work without having to call $apply.

$timeout is a wrapper around the native setTimeout with an important difference: $timeout will delay the execution at least until the next $digest cycle runs.

So passing in no delay will still delay the execution up until the next cycle. Passing in 2000 will delay the execution up to the next cycle after 2000ms.

Hence, this is an easy trick to make sure your changes are picked up by Angular without ever having to call $apply manually (which is considered unsafe in any case)

function MyCtrl($scope, $timeout) {
  $scope.items = [{name : "abc"},{name : "xyz"},{name : "cde"}];

  $scope.change = function(){
    test(function(testItem){
      $scope.items = testItem;
      //$scope.$apply();
    })
  }
  function test(callback){
    var testItem = [
                    {name : "mno"},
                    {name : "pqr"},
                    {name :   "ste"}
                   ];
    $timeout(function(){callback(testItem)},2000);
  }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...