Why is using if(!$scope.$$phase) $scope.$apply() an anti-pattern?

后端 未结 6 841
生来不讨喜
生来不讨喜 2020-11-28 02:24

Sometimes I need to use $scope.$apply in my code and sometimes it throws a \"digest already in progress\" error. So I started to find a way around this and foun

6条回答
  •  没有蜡笔的小新
    2020-11-28 02:46

    scope.$apply triggers a $digest cycle which is fundamental to 2-way data binding

    A $digest cycle checks for objects i.e. models(to be precise $watch) attached to $scope to assess if their values have changed and if it detects a change then it takes necessary steps to update the view.

    Now when you use $scope.$apply you face an error "Already in progress" so it is quite obvious that a $digest is running but what triggered it?

    ans--> every $http calls, all ng-click, repeat, show, hide etc trigger a $digest cycle AND THE WORST PART IT RUNS OF EVERY $SCOPE.

    ie say your page has 4 controllers or directives A,B,C,D

    If you have 4 $scope properties in each of them then you have a total of 16 $scope properties on your page.

    If you trigger $scope.$apply in controller D then a $digest cycle will check for all 16 values!!! plus all the $rootScope properties.

    Answer-->but $scope.$digest triggers a $digest on child and same scope so it will check only 4 properties. So if you are sure that changes in D will not affect A, B, C then use $scope.$digest not $scope.$apply.

    So a mere ng-click or ng-show/hide might be triggering a $digest cycle on over 100+ properties even when the user has not fired any event!

提交回复
热议问题