Controller Angularjs Statement

Asked

Viewed 2,843 times

3

Following the script below generated a doubt in which declaration to use, in the Angularjs documentation I found the two forms in different examples, but I did not find an explanation of which statement is used or if there is any specific case to use.

application.js:

//Declaração da aplicacao
$myApp = angular.module('myApp',[]);

//Declaração dos controllers
var controller1 = function ($scope,$http){
 $scope.name = 'controller declaracao 1';
}

$myApp.controller('controller2',[ '$scope', '$http', function($scope, $http) {
 $scope.name = 'controller declaracao 2';
}]);

index.html:

<html ng-app="myApp">
<body>
  <div ng-controller="controller1">{{name}}</div>
  <div ng-controller="controller2" >{{name}}</div>
</body>
</html>

Doubt which way to use? There is a difference in performance?

Example in Jsfiddle - https://jsfiddle.net/dyb8ne27/

3 answers

1

As far as performance is concerned, there is no difference. But there are some differences that I will list below:

What happens when Voce uses the (Directive) ng-controller directive:

  • A new Scope ($Scope) is created for each DOM element that uses the directive. Ie Voce can have the same view (template) with several elements using the same controller.
  • The relationship between element and controller is very explicit, since Voce knows that this controller is being defined for a specific DOM element
  • When you use Inspect (console), it will be much easier to see where exactly the controller is being used since the name ng-controller will be visible in HTML.

What happens when you set the controller via a route/url (route):

  • A new Scope ($Scope) is created for each route/url (route). That is, it will be available for all view (template) that is part of that route.
  • Through the estate resolve: {} of the route/url (route) Voce can inject dependencies into the controller
  • There is no direct relationship between the controller and the view. The relationship exists between the controller and the route/url (route).

There is no right or wrong way about declaring Controllers in Angularjs. Both ways are correct and work. Everything will really depend on your project requirements - and sometimes even personal preference.

An example scenario to use the controller via a route/url (route), eh when Voce needs to use the same template(view) for two different url/routes but the logic and data for each url/route should be different.

Since Voce needs to use the same template(view), Voce cannot use ng-controller in the view because it has to change depending on the route. So the solution is to define different controllers for each route and still use a single template.

I hope it helped.

1


claudsan its first controller works because it is being declared within the global Scope (window).

If you isolate Scope using IIFE (Immediately-Invoked Function Expression) your var controller1 will not be valid and your code will break because you will not find the variable.

example:

//Declaração da aplicacao
$myApp = angular.module('myApp',[]);

//Declaração dos controllers
var controller1 = function ($scope,$http){
 $scope.name = 'controller declaracao 1';
}

$myApp.controller('controller2',[ '$scope', '$http', function($scope, $http) {
 $scope.name = 'controller declaracao 2';
}]);

Error:

Error: [ng:areq] Argument 'controller1' is not a function, got undefined

Using IIFE you need to declare the controller1 the same as you declared the controller2, and Angular will get you access to the controler1:

(function() {
  'use strict';

  //Declaração da aplicacao
  $myApp = angular.module('myApp',[]);

  //Declaração dos controllers
  var controller1 = function ($scope,$http){
   $scope.name = 'controller declaracao 1';
  };

  $myApp.controller('controller1', ['$scope', '$http', controller1]);

  $myApp.controller('controller2',[ '$scope', '$http', function($scope, $http) {
   $scope.name = 'controller declaracao 2';
  }]);

}());

I hope I have helped and remember that it is always a good practice not to dirty the global Cope (window).

If you want to know more about the IIFE see this link

  • I was able to understand how it worked after a while, but thank you very much for the most detailed explanation that will possibly help more people.

0

I understand that your question refers to the difference between the version without declaration of dependency injections...

var controller1 = function ($scope,$http){}

and the version with addition to the injectables via method controller and with declaration of dependencies:

$myApp.controller('controller2',[ '$scope', '$http', function($scope, $http) {}]);

If that’s the case, let’s split:

No declaration of dependency injections

Your code is doing the following:

var             // Declaração de variável no escopo atual
controller1 =   // Nome do controller
function (      // A interface da função definirá as dependências
$scope,         // Injeta a dependência para o módulo $scope 
                //     usando o handler default
$http           // Injeta a dependência para o módulo $http
                //     usando o handler default
){
...             // Corpo da função
}

This format keeps the code lean and Terso. Dependencies are solved using your handlers standard, which is convenient if you are using a standard service repeatedly.

How Angular has no idea what controller1 means, it will map the DOM to find an object with the same name, make sure that the object is a function, and that this function can be mapped as a controller. It takes time - not much, but it’s a overhead.

With declaration of dependencies

$myApp          // Referência ao objeto que contém a aplicação
.controller(    // Declaração de controle 
'controller2',  // Nome do controller
[               // coleção de objetos; N referências a dependências,
                //     Último parâmetro será a função que as consome.
'$scope',       // Mapeando a dependência $scope para a posição 0
'$http',        // Mapeando a dependência $http para a posição 1
function(       // Interface da função
$scope,         // apelido (handler) da dependência na posição 0
$http           // apelido (handler) da dependência na posição 1
) {
...             // Corpo da função
}]);

This method is more complex, but offers more possibilities. Imagine you want to write a generic controller that expects to receive a dependency that has Get(id), Getall(), Remove methods().

Instead of rewriting your controller each time you need to implement a controller for each new implementation of this dependency, you only need to exchange the mapped reference. Example:

Original

$myApp.controller('dep1Controller',[ '$scope', 'dep1svc', function($scope, dependencia) {}]);

New version

$myApp.controller('dep2Controller',[ '$scope', 'dep2svc', function($scope, dependencia) {}]);

Internal controller functions will reference dependencia, completely ignorant if the called methods belong to dep1svc or dep2svc - thus allowing a greater abstraction of its code.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.