调用一个本地计算AngularJS表达式值的函数是不是很糟糕?

Mic*_*ord 0 angularjs angularjs-scope

我已经阅读了一篇关于使用范围的一些AngularJS陷阱的文章,并且它声明你不应该在表达式中使用函数,并且我理解每次框架认为需要时都可以评估表达式(这可能会发生很多)并且一遍又一遍地调用昂贵的功能是低效的.但是,如果该函数仅基于已经加载到范围中的值进行一些计算呢?例如,假设我有一个具有3个不同属性的范围,并且某些状态由这些属性值的组合决定.我可以在函数中计算该状态:

$scope.state = function() {
    return prop1 && prop2 && prop3;
};
Run Code Online (Sandbox Code Playgroud)

并从表达式中调用该函数.另一种方法是每次更改每个属性时调用该函数,以便缓存状态值:

$scope.prop1 = someValue;
$scope.state = getState();
...
$scope.prop2 = someOtherValue;
$scope.state = getState();
...
$scope.prop3 = yetAnotherValue;
$scope.state = getState();
Run Code Online (Sandbox Code Playgroud)

在这种情况下直接从表达式调用函数真的很糟糕吗?如果是这样,是唯一可以缓存计算值的替代方法,可能是在许多不同的地方,还是我还缺少另一种方法?

Ste*_*wie 5

不,这不是那么糟糕.

不在表达式中使用函数会导致HTML内联javascript膨胀.

考虑一下这段代码的优雅:

<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>
Run Code Online (Sandbox Code Playgroud)

与此相对:

<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>
Run Code Online (Sandbox Code Playgroud)
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 ...
  }
}
Run Code Online (Sandbox Code Playgroud)

甚至Angular的作者也鼓励在表达式中使用函数.

表达式中的函数在Angular中受欢迎,但有了这些前提:

  1. 功能应该是"轻"(在计算方面).
  2. 给定相同输入的函数应返回相同的输出.
  3. 函数应该是自包含的(它们不应该影响其他范围成员),否则它们可以创建$ digest循环.
  4. 函数应该是可缓存的(如果可能).