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

时间:2013-07-05 22:30:56

标签: angularjs angularjs-scope

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

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

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

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

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

2 个答案:

答案 0 :(得分: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>

与此相对:

<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 ...
  }
}

甚至Angular作者encourage在表达式中使用函数。

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

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

答案 1 :(得分:2)

一种选择是在状态条件下设置$watch$watch可以使用函数参数,因此您可以执行此操作:

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

Here is a minimal demo