最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin3浏览0评论

I have recently start using angular, and I'm coding one of my first controllers like that:

'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
                });
            })();

  }
]);

The thing is that I need the loadUsersTable to execute when the page loads, and I thought that using an inmmediatly invoked function could be the best and clearest option, but I can smell that this is not a good move for some reason that I don't know.

Maybe the best option is something like that, although you have to write more:

'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();

  }
]);

Could anyone point me the best practice to write this?

Thanks!

I have recently start using angular, and I'm coding one of my first controllers like that:

'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
                });
            })();

  }
]);

The thing is that I need the loadUsersTable to execute when the page loads, and I thought that using an inmmediatly invoked function could be the best and clearest option, but I can smell that this is not a good move for some reason that I don't know.

Maybe the best option is something like that, although you have to write more:

'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();

  }
]);

Could anyone point me the best practice to write this?

Thanks!

Share Improve this question asked Feb 13, 2015 at 8:12 victorgb6victorgb6 912 silver badges10 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 5

The immediately executed function is a design-pattern (Javascript Module Pattern) mostly used to avoid leaking variables and privates into the outer scope (a function scope, not an Angular scope, just to be clear). In this case, you already have a controller function scope, so you don't need this syntax.

One best practice I encountered is the use of an initialize function, which is called at the end of the controller.

Advantages:

  • The function name init clearly expresses what it does: run at the initialising of the controller;
  • You can clearly see all functions that are called.
  • You can keep your code ordering as you like, grouped by functionality for example.

In your case it would look like:

'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();
  }
]);

You don't need another function scope, the IIFE doesn't add anything here. Just put the code directly in the function:

'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
      });

  }
]);

Immediately-Invoked function doesn't have any binds with AngularJS! It is a JavaScript pattern, and depends on whether you NEED it or not.

Check some articles:

  • http://benalman./news/2010/11/immediately-invoked-function-expression/
  • http://esbueno.noahstokes./post/77292606977/self-executing-anonymous-functions-or-how-to-write

IIFE's are best practice as it prevents adding variables to global scope to prevent variable and function clashes. Your question talks about putting an IIFE inside a controller. Putting an IIFE in the controller doesn't really help as your controller isn't adding to global scope anyway and you shouldn't have many variables or functions added to the controller so the chance of having clashes is very small.

You could use an IIFE to wrap your controller, factories, directives as a good practice as they will prevent adding to global scope. For example the StakeholderViewController function won't be added to global scope:

(function() {
    'use strict';

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


    function StakeholderViewController($scope, stakeholderViewFactory) {
    }

}();

There's some good information in John Papa's style guide.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论