Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Not polluting global with angularjs

In angularjs, we define our controllers into window. While this would not create name clashes with other js modules and plugins, it is still not a good practise: a single application should expose a single object to the global namespace.

This is the usual way, defined in window:

function UserController($scope) { ... }

HTML:

<div ng-controller="UserController">

This is what I think of:

myApp.UserController = function ($scope) { ... };

So in that case, I should be initiating controller from html like this

<div ng-controller="myApp.UserController">

What do you think?

like image 971
Umur Kontacı Avatar asked Aug 25 '12 13:08

Umur Kontacı


2 Answers

One of the ways around it is to define it within Angular itself such as the way you described. In other words:

angular.module('YourApp').controller('ControllerName', function($scope) {})

I have confirmed the above method doesn't pollute the global namespace.

Edit: You also don't need to use <div ng-controller="myApp.UserController"> as you could define myApp in the attribute ng-app: <body ng-app="myApp"> That way you could call the ng-controller without prefixing myApp every time.

like image 189
Hengjie Avatar answered Nov 09 '22 22:11

Hengjie


The cleanest way of defining controllers is 1 per file. Each file should be wrapped with an immediately invoked function expression (IIFE) or closure that allows it to have its own local variables without polluting the global scope. This is the approach I take on my projects:

my-app.js - Primary Module Definition File - This file's main purpose is to define an application module and its dependencies, define routing (if routing is being used), and configure providers. In its simplest form it looks like this:

(function (angular) {
  angular.module('myApp', ['myApp.someFeature']);
}(angular));

some-feature/some-feature.js - feature module definition file - This file defines a module for a feature and any dependencies that this feature requires. This can be any logical grouping, not just a feature. This makes it very easy to bring the feature into another module or application if necessary.

(function (angular) {
  angular.module('myApp.someFeature', []);
}(angular));

some-feature/some-feature-controller.js - controller required for the feature - If the feature included multiple controllers, a more descriptive name would be needed, but lets assume this feature only needs 1 controller.

(function (angular) {
  function SomeFeatureController($scope) {
    ...
  }

  angular
    .module('myApp.someFeature')
    .controller('SomeFeatureController', SomeFeatureController);
}(angular));

index.html - Page html file - Pretty self explanatory

<html ng-app="myApp">
  <head>
    <title>My Angular App</title>
    <!-- Note: Angular and jQuery (if used) go in head so they delay view loading -->
    <script type="text/javascript" language="javascript" src="angular.js"></script>
  </head>
  <body ng-controller="SomeFeatureController">
    Content here....
    <!-- Note application files go at the end of the body so they do not delay view loading -->
    <script type="text/javascript language="javascript src="my-app.js">
    <script type="text/javascript language="javascript src="some-feature/some-feature.js">
    <script type="text/javascript language="javascript src="some-feature/some-feature-controller.js">
  </body>
</html>
like image 1
btesser Avatar answered Nov 09 '22 22:11

btesser