Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between controller and directives in angular js?

Tags:

angularjs

I am the beginner of angular js. I am struggling to understand the exact difference between the controller and directive in angular js.

like image 252
kalles Avatar asked May 06 '16 09:05

kalles


People also ask

What are controllers in AngularJS?

In AngularJS, a Controller is defined by a JavaScript constructor function that is used to augment the AngularJS Scope. Controllers can be attached to the DOM in different ways.

Which directive is used for controller in Angular?

AngularJS ng-controller Directive The ng-controller directive adds a controller to your application. In the controller you can write code, and make functions and variables, which will be parts of an object, available inside the current HTML element. In AngularJS this object is called a scope.

What is directives in AngularJS?

AngularJS directives are extended HTML attributes with the prefix ng- . The ng-app directive initializes an AngularJS application. The ng-init directive initializes application data. The ng-model directive binds the value of HTML controls (input, select, textarea) to application data.

What is the difference between the scopes of a directive and the scopes of a controller?

No difference. It is same object.


1 Answers

There's a bit too much going on here to be able to fully explain each so i'll try to give a brief explanation of each as well as an example.

Controllers

Use controllers to handle the logic of your views and assign the data you want to appear in your view. For example if in your application you have a page called "All Users" you want to display a list of users you would, define an array of users and attach it to the $scope object in your controller.

var myApp = angular.module('myApp',[]);

myApp.controller('allUsersController', ['$scope', function($scope) {
  $scope.users = [
    { name: "User 1", id: 1},
    { name: "User 2", id: 2},
    { name: "User 3", id: 3}
  ];
}]);

Attaching the users array to the scope allows you to access this data from the view. So now in the view you can use ng-repeat to output the list of users:

<ul>
 <li ng-repeat="user in users">{{user.name}}</li>
<ul>

Directives

Directives are mainly used for 2 things:

  1. Creating reusable components
  2. Manipulating the DOM

Directives are tricky to use at first but are extremely powerful, this statement from the docs is the reason why they are so powerful:

Directives are markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS's HTML compiler ($compile) to attach a specified behavior to that DOM element (e.g. via event listeners), or even to transform the DOM element and its children.

The main point to take away from that is that directives allow you to attach certain logic/behavior to a certain element, where as controllers usually only allow you to attach logic to pages/views.

Lets say that in the previous example we wanted to add some actions that can be done in the user list, maybe a like and dislike button. We could just create like and dislike buttons like this:

JS

var myApp = angular.module('myApp',[]);

myApp.controller('allUsersController', ['$scope', function($scope) {
  $scope.users = [
    { name: "User 1", id: 1, like: 0},
    { name: "User 2", id: 2, like: 0},
    { name: "User 3", id: 3, like: 0}
  ];

  $scope.like = function(user){
    user.like++;
  }

  $scope.dislike = function(user){
    user.like--;
  }
}]);

HTML

<ul>
 <li ng-repeat="user in users"> 
   {{user.name}}
   <button ng-click="like(user)">LIKE</button>
   <button ng-click="dislike(user)">DISLIKE</button> 
 </li>
<ul>

Fairly simple, we add like/dislike methods in our controller that increment/decrement the amount of likes a user has. This code will work fine, but what if i wanted to create another list of users in a different view? Say that you have 3 different views which contain user lists: "All Users", "My Friends" and "Recommended Users", all 3 will have a list of users that have the same actions (like or dislike) but the users displayed are different in each. We want to use the same like/dislike methods that we defined in our allUsersController but we are on a different view so we can't access them, so you would have to copy the same code into the controllers of the other views, might not seem like a big deal in our example but as applications get larger and more complicated this gets very tedious and hard to maintain.

This is where directives come in, instead of assigning the logic behind each user item in the controller you can define it in a directive:

app.directive('userItem', function() {
return {
    template: '<div>{{userData.name}} <button ng-click="like()">Like</button> <button ng-click="dislike()">Dislike</button>',
    scope: {
      userData: "="
    },
    link: function(scope, element, attrs) {
      scope.like = function(){
       scope.userData.like++;
      }

      scope.dislike = function(){
       scope.userData.like--;
      }
    }
}
});

In your html:

<div class="user_list>
   <user-item ng-repeat="user in users" user-data="user"></user-item>
</div>

By using the user-item directive you can now create a list of users anywhere in your application without having to redefine the logic that goes with each user. You'll notice that this also cleans up our html a bit and saves you on repeating code a lot. The directive wraps up your html and js into a reusable component.

EDIT: Regarding how we're passing the user data to the directive, this has to do with the isolate scope in directives which you can read about here. The basic idea is that it isolates the scope of the directive from the parent scope (allUsersController in our case), this is done to avoid unwanted clashes between the data in the 2 scopes and to promote re-usablity. But at the same time there is some data that we want the controller to share with the directive, so we "poke a hole" through the isolate scope to allow certain things in, which in our case is the userData defined in the directive scope.

You can visit the directives docs and scroll down to isolate scopes for more examples.

like image 155
Ahmed Wagdi Avatar answered Oct 10 '22 20:10

Ahmed Wagdi