1

我读过一篇关于使用 scopes 的一些 AngularJS 陷阱的文章,它指出你不应该在表达式中使用函数,而且我知道每次框架认为需要时都会评估表达式(这可能会发生很多)一遍又一遍地调用昂贵的函数是低效的。但是,如果该函数仅基于已加载到作用域中的值进行一些计算怎么办?例如,假设我有一个具有 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();

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

4

2 回答 2

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 作者也鼓励在表达式中使用函数。

Angular 中欢迎使用表达式中的函数,但要考虑以下几点:

  1. 函数应该是“轻量级的”(在计算方面)。
  2. 给定相同的输入,函数应该返回相同的输出。
  3. 函数应该是自包含的(它们不应该影响其他作用域成员),否则它们可能会创建一个 $digest 循环。
  4. 函数应该是可缓存的(如果可能的话)。
于 2013-07-05T23:42:08.927 回答
2

一种选择是设置$watch状态条件。 $watch可以采用函数参数,因此您可以这样做:

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

这是一个最小的演示

于 2013-07-05T22:46:09.093 回答