Angularjs 是否应该在$scope上声明每个函数?

Angularjs 是否应该在$scope上声明每个函数?,angularjs,angularjs-scope,Angularjs,Angularjs Scope,我想知道在$scope对象上声明函数的最佳实践是什么。如果我有一个函数没有在HTML页面上使用,它应该在$scope上声明吗 例如: $scope.pageModel = { variables } $scope.pageModel.btnSearchOnClick = function() { // some action } function randomFunction() { // some more actions } HTML中使用了btnSearc

我想知道在
$scope
对象上声明函数的最佳实践是什么。如果我有一个函数没有在HTML页面上使用,它应该在
$scope
上声明吗

例如:

$scope.pageModel = { variables }

$scope.pageModel.btnSearchOnClick = function() {
       // some action
}

function randomFunction() {
       // some more actions
}
HTML中使用了
btnSearchOnClick()
函数,例如:

<button name = "btnSearch" ng-click = "pageModel.btnSearchOnClick" ... >


但是,在使用此控制器的HTML中可能永远不需要
randomFunction()
函数,所以可以像上面那样声明它吗?或者控制器内的每个函数是否都应连接到
$scope

如果您要求,您设置它的方式比公开$scope上的所有内容更可取

我不确定在这个话题上是否有一个普遍的共识或“最佳实践”,所以我会同意你们的观点

不需要从$scope或视图调用的函数通常可以按照您的方式定义

我还喜欢做的是,如果一个函数变得非常重,并且暴露在$scope中,那么将它拆分为更小、更切点的函数,这些函数执行单独的任务

不将这些函数公开到$scope的缺点是缺乏可测试性(有人可能会说,您不关心单元测试中的内部实现)。一种解决方法是在控制器本身上定义它们。因此:

app.controller('someCtrl', function ($scope) {
  var ctrl = this;

  $scope.exposed = function () {
    ctrl.internal();
  });

  ctrl.internal = function () {
    console.log('Internal function called from $scope');
  });
});
这样,在单元测试中,您可以做类似的事情(请记住,这只是一个粗略的示例):


只将要从
$scope
访问的内容附加到
$scope
上。我有过这样的经历:没有scope,变量在任何地方都不可访问,所以你可以这样做,但有时,即使你在HTML中不需要它,它也会有用。我很偏执,所以我将大多数东西放在scope或服务对象中,这最终也会起到同样的作用。不过,我不确定这是最佳做法。
describe('someCtrl', function () {
  var Subject, $scope;

  beforeEach(function () {
    // setup...

    inject(function ($rootScope, $controller) {
      $scope = $rootScope.$new();

      Subject = $controller('someCtrl', {
        $scope: $scope
      });
    });
  });


  context('$scope', function () {
    it('has an exposed function', function () {
      expect($scope).to.have.property('exposed').and.to.be.a('function');
    });
  });

  context('internals', function () {
    it('has an internal function', function () {
      expect(Subject).to.have.property('internal').and.to.be.a('function');
    });
  });

});