Angular JS – Scope for custom Directives

If the placeholder of a directive is placed inside a controller we can refer his scope inside the template.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Angular JS</title>
</head>
<body data-ng-app="myApp">
    <div data-ng-controller="myController">
        <p>The full name is {{ firstName + " " + lastName }}</p>
 
        <my-directive>
        </my-directive>
    </div>
 
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
 
    <script type="text/javascript">
        angular.module("myApp", ["myApp.controllers", "myApp.directives"]);
        angular.module("myApp.controllers", []);
        angular.module("myApp.directives", []);
 
        angular.module("myApp.controllers").controller("myController", function ($scope) {
            $scope.firstName = "John";
            $scope.lastName = "Doe";
        });
 
        angular.module("myApp.directives").directive("myDirective", function () {
            return {
                restrict: "E",
                templateUrl: "Templates/Default09/myDirective.html"
            };
        });
    </script>
</body>
</html>

<div>
    <ul>
        <li>Name: {{firstName}}
        </li>
        <li>Surname: {{lastName}}
        </li>
    </ul>
</div>

Using an isolated scope for the directive

To use an isolated scope for the directive we have to use the scope property within our directive definition. The default value of this property is false, which means that we are inheriting the parent scope (the one of the controller in which our placeholder is). We can also set the scope property = true to work with a copy of the parent scope (our changes on the model will not affect the parent).

But the most interesting thing is that we can create our own scope for the directive using a JS object. Depending on the prefix we use while defining our scope elements we can have different behaviors for our directive.


Using the “@” prefix

If we use the “@” prefix we are binding our scope element to the value of a placeholder’s attribute. The name of the attribute should come after the “@” prefix, but we can just write “@” if the attribute’s name is equal to the scope element name. We can also refer to elements from the parent scope with the usual attribute binding: attribute=”{{ parentElement }}”.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Angular JS</title>
</head>
<body data-ng-app="myApp">
    <div data-ng-controller="myController">
        <p>The full name is {{ firstName + " " + lastName }}</p>
 
        <my-directive name="Tizio" surname="Caio">
        </my-directive>
    </div>
 
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
 
    <script type="text/javascript">
        angular.module("myApp", ["myApp.controllers", "myApp.directives"]);
        angular.module("myApp.controllers", []);
        angular.module("myApp.directives", []);
 
        angular.module("myApp.controllers").controller("myController", function ($scope) {
            $scope.firstName = "John";
            $scope.lastName = "Doe";
        });
 
        angular.module("myApp.directives").directive("myDirective", function () {
            return {
                restrict: "E",
                scope: {
                    firstName: "@name",
                    lastName: "@surname"
                },
                templateUrl: "Templates/Default09/myDirective.html"
            };
        });
    </script>
</body>
</html>

Using the “=” prefix

If we use the “=” prefix we are binding our scope element to a parent scope element whose name is referred by a placeholder’s attribute. Also in this case the name of the attribute should come after the “=” prefix, but we can just write “=” if the attribute’s name is equal to the scope element name. We can also refer to calculated elements with the usual syntax: attribute=”parentElement()”.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Angular JS</title>
</head>
<body data-ng-app="myApp">
    <div data-ng-controller="myController">
        <p>The full name is {{ firstName + " " + lastName }}</p>
 
        <my-directive name="firstName" surname="lastName">
        </my-directive>
    </div>
 
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
 
    <script type="text/javascript">
        angular.module("myApp", ["myApp.controllers", "myApp.directives"]);
        angular.module("myApp.controllers", []);
        angular.module("myApp.directives", []);
 
        angular.module("myApp.controllers").controller("myController", function ($scope) {
            $scope.firstName = "John";
            $scope.lastName = "Doe";
        });
 
        angular.module("myApp.directives").directive("myDirective", function () {
            return {
                restrict: "E",
                scope: {
                    firstName: "=name",
                    lastName: "=surname"
                },
                templateUrl: "Templates/Default09/myDirective.html"
            };
        });
    </script>
</body>
</html>

Using the “&” prefix

If we use the “&” prefix we are binding our scope element to a parent scope method whose name is referred by a placeholder’s attribute. Also in this case the name of the attribute should come after the “&” prefix, but we can just write “&” if the attribute’s name is equal to the scope element name. The method referred is not just a calculated property (for that we can use the “=” prefix), but is an action we want to bind to some particular event inside the template (for example a button click).

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Angular JS</title>
</head>
<body data-ng-app="myApp">
    <div data-ng-controller="myController">
        <p>The full name is {{ firstName + " " + lastName }}</p>
 
        <my-directive name="Tizio" surname="Caio" action="showMessage('MESSAGE')">
        </my-directive>
    </div>
 
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
 
    <script type="text/javascript">
        angular.module("myApp", ["myApp.controllers", "myApp.directives"]);
        angular.module("myApp.controllers", []);
        angular.module("myApp.directives", []);
 
        angular.module("myApp.controllers").controller("myController", function ($scope) {
            $scope.firstName = "John";
            $scope.lastName = "Doe";
            $scope.showMessage = function (msg) {
                alert(msg);
            };
        });
 
        angular.module("myApp.directives").directive("myDirective", function () {
            return {
                restrict: "E",
                scope: {
                    firstName: "@name",
                    lastName: "@surname",
                    action: "&"
                },
                templateUrl: "Templates/Default09/myDirective.html"
            };
        });
    </script>
</body>
</html>
<div>
    <ul>
        <li>Name: {{firstName}}
        </li>
        <li>Surname: {{lastName}}
        </li>
    </ul>
    <button data-ng-click="action()">ACTION</button>
</div>
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s