Angular 控制器内的立即调用函数,好的做法?

Immediately-Invoked Function inside of an Angular Controller, good practice?

我最近开始使用 angular,我正在为我的第一个控制器编写代码:

'use strict';
angular
  .module('stakeholder')
  .controller('StakeholderViewController', ['$scope','stakeholderViewFactory',
  function($scope, stakeholderViewFactory) {
    $scope.users = [];

    var loadUsersTable = (function(){
        stakeholderViewFactory.getAccessUsers({stakeholderId: 3}).
                  success(function(data, status, headers, config) {
                    $scope.users = data;
                  }).
                  error(function(data, status, headers, config) {
                    //TODO: Alert
                });
            })();

  }
]);

问题是我需要在页面加载时执行 loadUsersTable,我认为使用直接调用的函数可能是最好和最清晰的选择,但我可以闻到这对某些人来说不是一个好举动我不知道的原因。

也许最好的选择是这样的,尽管你必须写更多:

'use strict';
angular
  .module('stakeholder')
  .controller('StakeholderViewController',   ['$scope','stakeholderViewFactory',
  function($scope, stakeholderViewFactory) {
    $scope.users = [];

    var loadUsersTable = function(){
        stakeholderViewFactory.getAccessUsers({stakeholderId: 3}).
                  success(function(data, status, headers, config) {
                    $scope.users = data;
                  }).
                  error(function(data, status, headers, config) {
                    //TODO: Alert
                });
            };
     loadUsersTable();

  }
]);

谁能告诉我写这篇文章的最佳实践?

谢谢!

立即调用的函数与 AngularJS 没有任何绑定!这是一个 JavaScript 模式,取决于您是否需要它。

查看一些文章:

您不需要另一个函数作用域,IIFE 不会在此处添加任何内容。直接把代码放在函数里就可以了:

'use strict';
angular
  .module('stakeholder')
  .controller('StakeholderViewController', ['$scope','stakeholderViewFactory',
  function($scope, stakeholderViewFactory) {
    $scope.users = [];

    stakeholderViewFactory.getAccessUsers({stakeholderId: 3}).
      success(function(data, status, headers, config) {
        $scope.users = data;
      }).
      error(function(data, status, headers, config) {
        //TODO: Alert
      });

  }
]);

IIFE 是最佳实践,因为它阻止将变量添加到全局范围以防止变量和函数冲突。您的问题是关于将 IIFE 放入控制器中。将 IIFE 放入控制器中并没有真正的帮助,因为您的控制器无论如何都不会添加到全局范围,并且您不应该向控制器添加很多变量或函数,因此发生冲突的可能性非常小。

您可以使用 IIFE 来包装您的控制器、工厂和指令,这是一种很好的做法,因为它们会阻止添加到全局范围。例如,StakeholderViewController 函数不会添加到全局范围:

(function() {
    'use strict';

    angular
        .module('stakeholder')
        .controller('StakeholderViewController', ['$scope','stakeholderViewFactory', StakeholderViewController]);


    function StakeholderViewController($scope, stakeholderViewFactory) {
    }

}();

John Papa's style guide 中有一些有用的信息。

立即执行的函数是一个设计模式Javascript Module Pattern),主要用于避免将变量和私有变量泄漏到外部范围(函数范围 ,不是 Angular 范围,只是为了清楚)。在这种情况下,您已经有一个控制器功能范围,因此您不需要此语法。

我遇到的一个最佳实践是使用初始化函数,它在控制器的末尾调用。

优点:

  • 函数名init清楚地表达了它的作用:运行控制器初始化时;
  • 您可以清楚地看到所有被调用的函数。
  • 您可以根据需要保持代码顺序,例如按功能分组。

在你的情况下它看起来像:

'use strict';
angular
  .module('stakeholder')
  .controller('StakeholderViewController',   ['$scope','stakeholderViewFactory',
  function($scope, stakeholderViewFactory) {
    var loadUsersTable;
    $scope.users = [];


    function init(){
        loadUsersTable();
    };

    loadUsersTable = function(){
        stakeholderViewFactory.getAccessUsers({stakeholderId: 3}).
            success(function(data, status, headers, config) {
                $scope.users = data;
            }).
            error(function(data, status, headers, config) {
                //TODO: Alert
            }
        );
    };

    init();
  }
]);