Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why declaring a controller as variable within itself or using $scope

I have recently started to learn and use AngularJS and I'm still unclear about some concept.

My question is this: in my app I have a controller which uses $http to retrieve data from my back-end as soon as it is initialised. Following the excellent tutorial from CodeSchool on Angular I came up with this:

app.controller("agentController", function ($http) {
    var agentsCtrl = this;
    agentsCtrl.agents = [];
    $http.get("getAgents").success(function (data) {
        agentsCtrl.agents = data;
    });
...

HTML:

<div ng-controller="agentController as agentCtrl">
    <div ng-repeat="agent in agentCtrl.agents">
...

This works fine, but I'm unclear on why I would need to declare the controller as a variable within itself using this. From what I understand it's because by doing this I can then call it within the $http service, where the this keyword would return the wrong scope. Is this correct?

I found that this also works:

app.controller("agentController", function ($http, $scope) {
    $scope.agents = [];
    $http.get("getAgents").success(function (data) {
        $scope.agents = data;
    });

HTML:

<div ng-controller="agentController as agentCtrl">
    <div ng-repeat="agent in agents">
...

I guess this works because I explicitly inject the scope and use it within the service. Also, the HTML is now slightly different. In the first case I need to explicitly call agentCtrl.agents, while with scope simply call on agents. This is still because the variable is now declared on the scope rather than the controller? Is this correct?

What is the best practice to use in similar cases?

Thank you!

like image 784
RiccardoNovaglia Avatar asked Feb 19 '26 07:02

RiccardoNovaglia


2 Answers

You are asking regard 2 different approach - "Controller as" or "$scope".

$scope

Original usage for scope binding would be:

<div ng-controller="MainController">  
  {{ someObj.someProp }}
</div>
app.controller('MainController', function ($scope) {  
  $scope.someObj = {
    someProp: 'Some value.'
  };
});

"Controller as"

Using this technique you can use the bind as follows:

<div ng-controller="MainController as main">  
  {{ main.someProp }}
</div>  
app.controller('MainController', function () {  
  this.someProp = 'Some value.'
});

Both work and, both fine. The major difference is preference.

Still, most of the community prefers 'Controller as', why?

  1. Readable - You can always look on a DOM element and understand what scope's model is bound to
  2. Testable - Not having to inject a $scope makes the test code slightly easier
  3. More suited to the vision of angular 2.0 where the controller is much more a constructor function than a function that adds stuff to $scope
like image 51
Ben Diamant Avatar answered Feb 21 '26 21:02

Ben Diamant


Question 1:

You have to save the reference to scope var agentsCtrl = this because your are creating a anonymous function to be used as a callback. When you do it the context variable (this) will be window.

app.controller("agentController", function ($http) {
    // this == your controller
    var agentsCtrl = this;

    $http.get("getAgents").success(function (data) {
        // Anonymous function 
        // this == Window Object
    });
});

Question 2:

$scope is the glue between application controller and the view. you can reference it as a global variable that you can have access both from view and from controllers.

$scope.agents = []; // From controller

And

{{ agents }} // From view (you don't need to specify the $scope variable)

I prefer to give an alias for the controler and use it in my HTML as you did in

<div ng-controller="agentController as agentCtrl">
    <div ng-repeat="agent in agents">
...

But both ways are correct and will work fine.

like image 37
nanndoj Avatar answered Feb 21 '26 20:02

nanndoj



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!