Isn't it good to call a function that locally computes a value from an AngularJS expression?

I read an article about some AngularJS traps using scopes , and it says that you should not use a function in expressions, and I understand that an expression can be evaluated every time the structure considers it necessary (and this can happen a lot), and there was It would be inefficient to repeatedly call an expensive function. But what if this function performs only some calculations based on the values ​​already loaded into the region? For example, suppose I have a region with three different properties, and some state is determined by a combination of the values ​​of these properties. I can calculate this state in a function:

$scope.state = function() {
    return prop1 && prop2 && prop3;
};

and call this function from the expression. An alternative would be to call a function every time each of the properties is changed so that the state value is cached:

$scope.prop1 = someValue;
$scope.state = getState();
...
$scope.prop2 = someOtherValue;
$scope.state = getState();
...
$scope.prop3 = yetAnotherValue;
$scope.state = getState();

Is it really so bad to call a function directly from an expression in this case? If so, is this the only alternative to caching the computed value, potentially in many different places, or is there some other approach that I am missing?

0
source share
2 answers

No, this is not so bad.

Unused functions in expressions will cause HTML to bloat with inline javascript.

Consider the elegance of this code:

<span ng-show="(form.firstName.$dirty || submitted) && form.firstName.$error.required">First name is required!</span>
...
<span ng-show="(form.lastName.$dirty || submitted) && form.lastName.$error.required">Last name is required!</span>
...
<span ng-show="(form.email.$dirty || submitted) && form.email.$error.required">Email is required!</span>

in comparison with this:

<span ng-show="isInvalid('firstName')">First name is required!</span>
...
<span ng-show="isInvalid('lastName')">Last name is required!</span>
...
<span ng-show="isInvalid('email')">Email is required!</span>
function Ctrl($scope){
  $scope.isInvalid = function(field){
    return ($scope.form[field].$dirty || $scope.submitted) && $scope.form[field].$error.required;
  };

  $scope.submit = function(){
    $scope.submitted = true;
    // $http.post ...
  }
}

Even Angular authors encourage the use of functions in expressions.

Angular, forethoughts:

  • "" ( ).
  • .
  • ( ), $digest.
  • ( ).
+5

- $watch . $watch , :

$scope.$watch(function(){
    return $scope.prop1 && $scope.prop2 && $scope.prop3;        
},function(val){
    $scope.state = val;
});

+2

All Articles