7

当我创建控制器时,我总是向$scope对象添加函数,如下所示:

function DummyController($scope) {

  $scope.importantFunction = function () { /*...*/ };

  $scope.lessImportantFunction = function () { /*...*/ };

  $scope.bussinessLogicFunction = function () { /*...*/ };

  $scope.utilityFunction = function () { /*...*/ };

}

当然,我会很好地封装我的控制器,确保业务逻辑位于适当的组件(通过 DI 注入)或服务中。因此控制器专注于协调 UI 和后端之间的事情。

但是,正如您所看到的 - 仍然有许多不同类型的功能。我喜欢保留更多,因为它提高了恕我直言的可读性。

问题 是将许多函数附加到 $scope 对象是一个好习惯吗?它有性能开销吗?我知道这$scope是一种特殊的对象,在 Angular 的摘要周期中不断被评估,所以我这样做是对的,还是坚持我的方法会自找麻烦?

(请注意:我不是在寻找替代方法。我在寻找对了解 Angular 内部结构的人的一些深思熟虑的分析。)

谢谢!

更新:

Anders 的回答非常好,向您展示了一些可以遵循的路径。今天碰到了这个美女,一个Angular Js 调试和性能监控的 chrome 扩展。它向您展示了所有范围和分配的变量,以及一些有趣的性能图表。任何 Angular 开发人员都必须拥有!

4

1 回答 1

16

更新:

  1. 我应该将所有函数和变量添加到范围吗?

    不,如果您需要在模板中访问它们,您应该只将函数和变量添加到您的范围。仅在控制器函数中访问的变量不应该在范围内,它应该是控制器函数的本地变量。

  2. 如果我在范围内添加很多功能会影响性能吗?

    一般来说,没有。在您的范围内执行的函数ng-click="myFunction()"不应以明显的方式影响性能。但是如果你的函数是这样执行的:{{myFunction()}}它将为每个摘要执行,因为 Angular 需要知道它的返回值是否已更改,以便它可以更新 UI。

  3. 如果我在作用域中添加很多变量会影响性能吗?

    如果你在 Angular 会脏检查它们的地方使用它们,它可能会影响性能。这些情况是您将它们打印出来的地方{{myVariable}},如果您在ng-model="myVariable",ng-show="myVariable"等中使用它们。类似的指令ng-click不会执行脏检查,因此不会减慢速度。Angular 背后的人建议你不要在一页上使用超过 2000 个需要重新绘制/脏检查的表达式,因为在那之后你的性能会开始下降。2000 的限制是他们在研究 Angular 性能时发现的。

    请注意,仅仅因为您在范围上添加了一个属性,并不意味着 Angular 会对它执行脏检查。它们必须在您的模板中使用才能执行脏检查(但不能用于 ng-click)。

  4. 如果我想在我的 Angular 应用程序中获得最佳性能,我应该注意什么?

    就像我上面提到的,尝试将绑定模板表达式的数量保持在 2000 以下。如果您在您的范围内实现 watch,请确保 watch 的表达式执行得非常快。这是你不应该这样做的一个例子:

    $scope.items = [];
    for (var i = 0; i < 1000; i++) {
        $scope.items.push({prop1: 'val1', prop2: 'val2', prop3: 'val3'});
    }
    
    $scope.$watch('items', function() {
    
    }, true);
    

    通过将true第三个参数添加到 $watch 中,您是在告诉 Angular 循环遍历$scope.items每个摘要周期以检查一千个项目的任何属性是否已更改,这在时间和内存上都将耗费大量时间。

    你应该做的是:

    $scope.items = [];
    for (var i = 0; i < 1000; i++) {
        $scope.items.push({prop1: 'val1', prop2: 'val2', prop3: 'val3'});
    }
    
    $scope.$watch('items.length', function() {
    
    });
    

    也就是说,仅检查何时$scope.items.length更改。该表达式将执行得非常快。


原帖:

如果您的问题是“向模板公开函数是否比对象更好”,那么是的,您应该尽可能多地使用函数。这样你就可以将逻辑封装在控制器内部,而不是让它渗入你的模板。举个例子:

<div ng-show="shouldShow">Toggled div</div>
<button ng-click="shouldShow = !shouldShow">Toggle<button>

这里的模板对正在发生的事情有太多的了解。相反,这应该像这样解决:

// controller
var shouldShow = false;
scope.toggle = function() {
    shouldShow = !shouldShow;
}
scope.shouldShow = function() {
    return shouldShow;
}

<!-- template -->
<div ng-show="shouldShow()">Toggled div</div>
<button ng-click="toggle()">Toggle<button>

通过这样做,在不触及模板的情况下扩展控制器中的逻辑是微不足道的。虽然您现在的要求可能只是在按下按钮时切换 div,但明天的要求可能是在发生这种情况时更新应用程序的其他部分。如果您改用函数,则可以很容易地在函数中添加该逻辑,而无需更改模板。

作用域上的函数比使用属性的开销要多一些,但是当那一天到来时,这些开销可能不会成为减慢应用程序速度的原因。所以在有意义的时候使用函数。

但是你仍然应该尽量保持你的控制器尽可能小。如果它们增长到包含大量功能/功能,您可能应该将您的控制器拆分为可重用的指令。

于 2013-02-22T08:21:07.513 回答