A Controller for a Directive

Introduction

We already know that the most common way to send (a) value(s) to a view is to create a controller, add (a) value(s) to it using either the this object or a $scope service. As an alternative, a custom directive can have its own controller, in which case you would not need a module controller to send data to a view. To make this happen, you have many options.

If you want your custom directive to control the value(s) it sends to a value, one option is to first create a module controller. In its constructor, you can use the this object to add the value(s) and/or function you will access in the view. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Traffic Ticket System</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="trafficSystem">
    <h1>Traffic Ticket System</h1>
    
    <div ng-controller="OffenseTypesController as otc">
        <p><b>Introduction:</b> {{otc.introduction}}</p>
        <p><b>Stop Sign Violation:</b> {{otc.stop}}</p>
        <p><b>Speeding Violation:</b> {{otc.speed}}</p>
    </div>

<script type="text/javascript">
    var appTraffic = angular.module('trafficSystem', []);

    appTraffic.controller('OffenseTypesController', [function () {
        this.introduction = "Our traffic ticket system considers various types of violations including driving through a Stop Sign, speeding, driving through a red light, etc.";
        this.stop = "When coming to a Stop Sign, a vehicle operator is required to stop completely regardless of anything else going on.";
        this.speed = "In most streets and roads of our county, speed limit signs are clearing posted. Except for emergency vehicles, every car is required to obey those speed limits.";
    }]);
</script>
</body>
</html>

To let you create a controller for a custom directive, the object returned by the directive is equipped with a property named controller. To omit a controller in a view, add this property and set its value as the name of a module controller. This can be done as follows:

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

appTraffic.controller('OffenseTypesController', [function () {
        . . .
}]);

appTraffic.directive('introductoryTopic', function () {
    return {
        controller: 'OffenseTypesController'
    };
});

Practical LearningPractical Learning: Introducing Directive Control

  1. Start Microsoft Visual Studio
  2. On the main menu, click File -> New -> Project...
  3. In the middle list, click ASP.NET Web Application (.NET Framework) and set the project Name to TrafficTicketsManagement2
  4. Click OK
  5. In the New ASP.NET Web Application dialog box, click the MVC icon and click OK
  6. In the Solution Explorer, right-click TrafficTicketsManagement2 and click Manage NuGet Packages...
  7. In the NuGet tab, click Browser and, in the text box, type angularjs
  8. In the list, click angularjs
  9. Click Install.
    If a message box displays, click OK
  10. In the Solution Explorer, right-click Content -> Add -> Style Sheet
  11. Type TrafficTicketsSystem
  12. Click OK
  13. Create some styles as follows:
    body {
        background-color: #FFFFFF;
    }
    
    .bold               { font-weight:      600;            }
    .blue               { color:            #0d3bcf;        }
    .left-right-border  { border-left:      1px solid gray;
                          border-right:     1px solid gray; }
    .top-border         { border-top:       1px solid #0d3bcf;
                          padding-top:      1.05em;         }
    .topic-title        { color:            maroon;
                          padding-bottom:   0.25em;
                          border-bottom:    1px solid gray; }
    .common-font        { font-family:      Georgia, Garamond, 'Times New Roman', serif; }
    
  14. In the Solution Explorer, right-click TrafficTicketsManagement2 -> Add -> New Folder
  15. Type DriversIssues
  16. In the Solution Explorer, right-click DriversIssues -> Add -> HTML Page
  17. Type Violations as the name of the file
  18. Click Add
  19. In the Solution Explorer, right-click Scripts -> Add > JavaScript File
  20. Type TrafficTicketsSystem as the name of the file
  21. Click OK
  22. In the document, type the following code:
    var appTicketSystem = angular.module('appTrafficTicketsSystem', []);
    
    appTicketSystem.directive('mainTitle', function () {
        var ticket = {
            restrict: "E",
            template: "<h2 class='topic-title common-font text-center bold'>Drivers/Owners Related Issues</h2>"
        };
    
        return ticket;
    });
    
    appTicketSystem.directive('trafficViolations', function () {
        return {
            restrict: "E",
            templateUrl: "/DriversIssues/Violations.html"
        }
    });
    
    appTicketSystem.controller('ViolationsTypesController', [function () {
        this.introduction = "Our traffic ticket system considers various types of violations including driving through a Stop Sign, speeding, driving through a red light, etc.";
        this.stop = "When coming to a Stop Sign, a vehicle operator is required to stop completely regardless of anything else going on.";
        this.speed = "In most streets and roads of our county, speed limit signs are clearing posted. Except for emergency vehicles, every car is required to obey those speed limits.";
        this.red = "A red light is probably the highest signal of a dangerous situation. When coming to a traffic signal that has a red light, whether steady or blinking, the vehicle must completely stop.";
    }]);
  23. In the Solution Explorer, expand App_Start and double-click BundleConfig.cs
  24. Change the document as follows:
    using System.Web.Optimization;
    
    namespace TrafficTicketsManagement2
    {
        public class BundleConfig
        {
            // For more information on bundling, visit https://go.microsoft.com/fwlink/?LinkId=301862
            public static void RegisterBundles(BundleCollection bundles)
            {
                bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                            "~/Scripts/jquery-{version}.js",
                            "~/Scripts/angular.js",
                            "~/Scripts/TrafficTicketsSystem.js"));
    
                  bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                            "~/Scripts/jquery.validate*"));
    
                // Use the development version of Modernizr to develop with and learn from. Then, when you're
                // ready for production, use the build tool at https://modernizr.com to pick only the tests you need.
                bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
                            "~/Scripts/modernizr-*"));
    
                bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
                          "~/Scripts/bootstrap.js",
                          "~/Scripts/respond.js"));
    
                bundles.Add(new StyleBundle("~/Content/css").Include(
                          "~/Content/bootstrap.css",
                          "~/Content/site.css",
                          "~/Content/TrafficTicketsSystem.css"));
            }
        }
    }
  25. In the Solution Explorer, expand Controllers and double-click HomeController.cs
  26. Create an action method named DriversIssues
    using System.Web.Mvc;
    
    namespace TrafficTicketsManagement2.Controllers
    {
        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                return View();
            }
    
            public ActionResult About()
            {
                ViewBag.Message = "We are in charge of issuing traffic tickets, management them, and collecting their payments.";
    
                return View();
            }
    
            public ActionResult Contact()
            {
                ViewBag.Message = "Let us know any type of concern or issue that crosses your mind.";
    
                return View();
            }
    
            public ActionResult DriversIssues() => View();
            }
        }
    }
  27. In the document, right-click DriversIssues and click Add View...
  28. In the Add View dialog box, make sure the View Name text box displays DriversIssues. Click Add
  29. Change the document as follows:
    @{
        ViewBag.Title = "Drivers/Owners Related Issues";
    }
    
    @Scripts.Render("~/bundles/jquery")
    
    <div ng-app="appTrafficTicketsSystem">
        <main-title></main-title>
    
        <div>
            <traffic-violations></traffic-violations>
        </div>
    </div>
  30. To execute, on the main menu, click Debug -> Start Without Debugging:

    Creating a Directive

  31. Return to your programming environment

An Instance of a Controller

Remember that if you use the this object to add properties to a controller, you must use an instance of the controller to access the values of those properties. As a result, the value of the controller property should include an instance of the module controller. Here is an example:

appTraffic.directive('introductoryTopic', function () {
    return {
        controller: 'OffenseTypesController as otc'
    };
});

Once again, to specify how the directive would display its content, add a template property to the directive object. For the value of that property using {{}} placeholder to include the value(s) of the module controller. You can then access the directive in the view.

Practical LearningPractical Learning: Using an Instance of a Controller

  1. Access the TrafficTicketsSystem.js file and add the following code to its bottom section:
    . . . No Change
    
    appTicketSystem.directive('violationsTopics', function () {
        return {
            controller: 'ViolationsTypesController as vtc',
            template: "<p class='common-font'><b>Overview:</b> {{vtc.introduction}}</p>" +
            "<p class='common-font'><b>Stop Sign Violation:</b> {{ vtc.stop }}</p>" +
            "<p class='common-font'><b>Speeding Violation:</b> {{ vtc.speed }}</p>" +
            "<p class='common-font'><b>Red Light Violation:</b> {{ vtc.red }}</p>"
        };
    });
  2. Access the Violations.html file and add the following two lines below the body tag (in fact, you can delete the whole content and replace it with the following two lines):
    . . . No Change
    <body>
    <p>Take a look at how traffic violations function, are anlyzed, and are issued.</p>
    
    <violations-topics></violations-topics>
    </body>
    </html>
  3. In the Solution Explorer, expand Views and expand Shared
  4. Double-click _Layout.cshtml
  5. Type the following code:
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width" />
        <title>Traffic Ticket System :: @ViewBag.Title</title>
        @Styles.Render("~/Content/css")
        @Scripts.Render("~/bundles/modernizr")
    </head>
    <body>
        <div class="navbar navbar-inverse navbar-fixed-top">
            <div class="container">
                <div class="navbar-header">
                    <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    @Html.ActionLink("Traffic Ticket System", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
                </div>
                <div class="navbar-collapse collapse">
                    <ul class="nav navbar-nav">
                        <li>@Html.ActionLink("Home", "Index", "Home")</li>
                        <li>@Html.ActionLink("About", "About", "Home")</li>
                        <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
                    </ul>
                </div>
            </div>
        </div>
        <div class="container body-content">
            @RenderBody()
        </div>
    
        <div class="top-border container common-font">
            <p class="text-center">@Html.ActionLink("Drivers/Tickets Related Issues", "DriversIssues")</p>
            <p class="text-center">&copy; @DateTime.Now.Year - Traffic Ticket System</p>
        </div>
    
        @Scripts.Render("~/bundles/jquery")
        @Scripts.Render("~/bundles/bootstrap")
        @RenderSection("scripts", required: false)
    </body>
    </html>
  6. To save everything, on the Standard toolbar, click the Save All button Save All
  7. Return to the browser and refresh it

    Creating a Directive

  8. Return to your programming environment
  9. In the Solution Explorer, right-click DriversIssues -> Add -> HTML Page
  10. Type Cameras
  11. Press Enter
  12. Change the document as follows:
    . . .
    <body>
    <p>This is a description of the cameras used by our traffic system, including how they operate.</p>
    
    <cameras-issues></cameras-issues>
    
    </body>
    </html>
  13. Remember that you can use various module controllers in a webpage. In the same way, you can create various module controllers and apply each to a different custom directive used on the same webpage. To apply some examples, access the TrafficTicketsSystem.js and change the file as follows:
    var appTicketSystem = angular.module('TrafficTicketsSystem', []);
    
    appTicketSystem.directive('mainTitle', function () {
        return {
            restrict: "E",
            template: "<h2 class='topic-title common-font text-center bold'>Ticket Processing</h2>"
        };
    });
    
    appTicketSystem.directive('trafficViolations', function () {
        return {
            restrict: "E",
            templateUrl: "/DriversIssues/Violations.html"
        }
    });
    
    appTicketSystem.directive('camerasSummary', function () {
        return {
            restrict: "E",
            templateUrl: "/DriversIssues/Cameras.html"
        }
    });
    
    appTicketSystem.controller('ViolationsTypesController', [function () {
        this.introduction = "Our traffic ticket system considers various types of violations including driving through a Stop Sign, speeding, driving through a red light, etc.";
        this.stop = "When coming to a Stop Sign, a vehicle operator is required to stop completely regardless of anything else going on.";
        this.speed = "In most streets and roads of our county, speed limit signs are clearing posted. Except for emergency vehicles, every car is required to obey those speed limits.";
        this.red = "A red light is probably the highest signal of a dangerous situation. When coming to a traffic signal that has a red light, whether steady or blinking, the vehicle must completely stop.";
    }]);
    
    appTicketSystem.controller('CamerasTopicsController', [function () {
        this.introduction = "Our traffic ticket system uses the most precise and accurate cameras on the markets. They use the latest technologies and image development in terms of speed and resolution.";
        this.speed = "Our cameras take their pictures and videos in the fractional time it take regular cameras to act. For all red light and Stop Sign violations, we provide pictures and videos to meet the highest demanding requirements.";
        this.demonstrations = "We have various demonstrations of our cameras on our Web site. We also regularly conduct public demonstrations for various stakeholders. If you are interested in taking part of one of our demonstrations, please contact us to set up an appointment. The demonstration can be performed for an individual's interest or for a group.";
    }]);
    
    appTicketSystem.directive('violationsTopics', function () {
        return {
            controller: 'ViolationsTypesController as otc',
            template: "<p><b>Overview:</b> {{otc.introduction}}</p>" +
                      "<p><b>Stop Sign Violation:</b> {{ otc.stop }}</p>" +
                      "<p><b>Speeding Violation:</b> {{ otc.speed }}</p>" +
                      "<p><b>Red Light Violation:</b> {{ otc.red }}</p>"
        };
    });
    
    appTicketSystem.directive('camerasIssues', function () {
        return {
            controller: 'CamerasTopicsController as ctc',
            template: "<p><b>Overview:</b> {{ctc.introduction}}</p>" +
                      "<p><b>Cameras Speed:</b> {{ ctc.speed }}</p>" +
                      "<p><b>Image/Videos Demonstrations:</b> {{ ctc.demonstrations }}</p>"
        };
    });
  14. Access the Violations.html file and change it as follows:
    . . . No Change
    <body>
    <violations-topics></violations-topics>
    </body>
    </html>
  15. Access the DriversIssues.cshtml document and change it as follows:
    @{
        ViewBag.Title = "Drivers/Owners Related Issues";
    }
    
    @Scripts.Render("~/bundles/jquery")
    
    <div ng-app="ticketSystem">
        <main-title></main-title>
    
        <div class="row">
            <div class="col-md-6 common-font">
                <traffic-violations></traffic-violations>
            </div>
            <div class="col-md-6 common-font">
                <cameras-issues></cameras-issues>
            </div>
        </div>
    </div>
  16. To save everything, on the Standard toolbar, click the Save All button Save All
  17. Return to the browser and refresh it

    An Instance of a Controller

  18. Return to your programming environment

A Scope Service for a Directive

A Scope Service for a Controller

In the above module controllers, we use the this object to create the values that would be accessed in the view. As an alternative, you can use the $scope service for the same goal. Here are examples:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Traffic Ticket System</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="trafficSystem">
    <h1>Traffic Ticket System</h1>

    <introductory-topic></introductory-topic>

<script type="text/javascript">
    var appTraffic = angular.module('trafficSystem', []);

        appTraffic.controller('OffenseTypesController', ['$scope', function ($scope) {
            $scope.introduction = "Our traffic ticket system considers various types of violations including driving through a Stop Sign, speeding, driving through a red light, etc.";
            $scope.stop = "When coming to a Stop Sign, a vehicle operator is required to stop completely regardless of anything else going on.";
            $scope.speed = "In most of our streets and roads of our county, speed limit signs are clearly posted. Except for emergency vehicles, every car is required to obey those speed limits.";
            $scope.red = "A red light is probably the highest signal of a dangerous situation. When coming to a traffic signal that has a red light, whether steady or blinking, the vehicle must completely stop.";
        }]);

    appTraffic.directive('introductoryTopic', function () {
        return {
            controller: 'OffenseTypesController',
            template: "<p><b>Introduction:</b> {{introduction}}</p>" +
                      "<p><b>Stop Sign Violation:</b> {{ stop }}</p>" +
                      "<p><b>Speeding Violation:</b> {{ speed }}</p>" +
                      "<p><b>Red Light Violation:</b> {{ red }}</p>"
        };
    });
</script>
</body>
</html>;

In the same way, you can add all types of members to the this or the $scope objects.

Practical LearningPractical Learning: Using the Scope Service for a Controller

  1. Access the TrafficTicketsSystem.js file and change it as follows:
    var appTicketSystem = angular.module('ticketSystem', []);
    
    appTicketSystem.directive('mainTitle', function () {
        return {
            restrict: "E",
            template: "<h2 class='topic-title common-font text-center bold'>Drivers/Owners Related Issues</h2>"
        };
    });
    
    appTicketSystem.directive('trafficViolations', function () {
        return {
            restrict: "E",
            templateUrl: "/DriversIssues/Violations.html"
        }
    }).directive('camerasSummary', function () {
        return {
            restrict: "E",
            templateUrl: "/DriversIssues/Cameras.html"
        }
    }).directive('vehicleOperators', function () {
        return {
            restrict: "E",
            templateUrl: "/DriversIssues/Drivers.html"
        }
    });
    
    appTicketSystem.controller('ViolationsTypesController', [function () {
        this.introduction = "Our traffic ticket system considers various types of violations including driving through a Stop Sign, speeding, driving through a red light, etc.";
        this.stop = "When coming to a Stop Sign, a vehicle operator is required to stop completely regardless of anything else going on.";
        this.speed = "In most streets and roads of our county, speed limit signs are clearing posted. Except for emergency vehicles, every car is required to obey those speed limits.";
        this.red = "A red light is probably the highest signal of a dangerous situation. When coming to a traffic signal that has a red light, whether steady or blinking, the vehicle must completely stop.";
    }]).controller('CamerasTopicsController', [function () {
        this.introduction = "Our traffic ticket system uses the most precise and accurate cameras on the markets. They use the latest technologies and image development in terms of speed and resolution.";
        this.speed = "Our cameras take their pictures and videos in the fractional time it take regular cameras to act. For all red light and Stop Sign violations, we provide pictures and videos to meet the highest demanding requirements.";
        this.demonstrations = "We have various demonstrations of our cameras on our Web site. We also regularly conduct public demonstrations for various stakeholders. If you are interested in taking part of one of our demonstrations, please contact us to set up an appointment. The demonstration can be performed for an individual's interest or for a group.";
    }]).controller('DriversController', ['$scope', function ($scope) {
        $scope.description = "Our primary goal in this county is to have safe, concerned, comfortable, but especially responsible drivers. We have street signs everywhere to keep you alert. While our roads provide you with convenient ways to move around the county, we also urge our drivers and multiple vehicle operators to be considerate not only of their environment and surrounding but also of other people whether they are pedestrians our are also driving. Consider that the roads are yours to share.";
        $scope.contact = "If you have any issue or concerns about our traffic cameras or the traffic ticketing system, please don't hesitate to contact us. You can contact us individually, as a group, as an organization, or by an authority of your choice, by phone, email, a form on our Web site, or a mailed letter."
    }]);
    
    appTicketSystem.directive('violationsTopics', function () {
        return {
            controller: 'ViolationsTypesController as vtc',
            template: "<p><b>Overview:</b> {{vtc.introduction}}</p>" +
                      "<p><b>Stop Sign Violation:</b> {{ vtc.stop }}</p>" +
                      "<p><b>Speeding Violation:</b> {{ vtc.speed }}</p>" +
                      "<p><b>Red Light Violation:</b> {{ vtc.red }}</p>"
        };
    }).directive('camerasIssues', function () {
        return {
            controller: 'CamerasTopicsController as ctc',
            template: "<p><b>Overview:</b> {{ctc.introduction}}</p>" +
                      "<p><b>Cameras Speed:</b> {{ ctc.speed }}</p>" +
                      "<p><b>Image/Videos Demonstrations:</b> {{ ctc.demonstrations }}</p>"
        };
    }).directive('driversConcerns', function () {
        return {
            controller: 'DriversController',
            template: "<p><b>Description:</b> {{ description }}</p>" +
                      "<p><b>Contact Us:</b> {{ contact }}</p>"
        };
    });
  2. In the Solution Explorer, right-click TicketsManagement -> Add -> HTML Page
  3. Type Drivers
  4. Press Enter
  5. Change the document as follows:
    . . . No Change
    <body>
    
    <drivers-concerns></drivers-concerns>
    
    </body>
    </html>
  6. Access the Cameras.html file and keep only the directive in it:
    . . . No Change
    <body>
    
    <cameras-issues></cameras-issues>
    
    </body>
    </html>
  7. Access the DriversIssues.cshtml file and change it as follows:
    @{
        ViewBag.Title = "Tickets Management";
    }
    
    @Scripts.Render("~/bundles/angular")
    
    <div class="common-font" ng-app="ticketSystem">
        <main-title></main-title>
    
        <div class="row common-font">
            <div class="col-md-4">
                <traffic-violations></traffic-violations>
            </div>
            <div class="col-md-4 left-right-border">
                <cameras-issues></cameras-issues>
            </div>
            <div class="col-md-4">
                <vehicle-operators></vehicle-operators>
            </div>
        </div>
    </div>
  8. To save everything, on the Standard toolbar, click the Save All button Save All
  9. Return to the browser and refresh it

    An Instance of a Controller

  10. As an alternative to creating an instance of a module controller in the controller property of a directive, the object returned by a custom directive is equipped with a property named controllerAs. Add this property and set its value as the desired instance name. Then, in the template, use that controllerAs value.
    For an example, access the TrafficTicketsSystem.js file and change the document as follows::
    . . . No Change
    
    appTicketSystem.directive('violationsTopics', function () {
        return {
            controller: 'ViolationsTypesController',
            controllerAs: 'summary',
            template: "<p><b>Overview:</b> {{ summary.introduction }}</p>" +
                      "<p><b>Stop Sign Violation:</b> {{ summary.stop }}</p>" +
                      "<p><b>Speeding Violation:</b> {{ summary.speed }}</p>" +
                      "<p><b>Red Light Violation:</b> {{ summary.red }}</p>"
        };
    }).directive('camerasIssues', function () {
        return {
            controller: 'CamerasTopicsController',
            controllerAs: 'topic',
            template: "<p><b>Overview:</b> {{ topic.introduction}}</p>" +
                      "<p><b>Cameras Speed:</b> {{ topic.speed }}</p>" +
                      "<p><b>Image/Videos Demonstrations:</b> {{ topic.demonstrations }}</p>"
        };
    }).directive('driversConcerns', function () {
        return {
            controller: 'DriversController',
            template: "<p><b>Description:</b> {{ description }}</p>" +
                      "<p><b>Contact Us:</b> {{ contact }}</p>"
        };
    });
  11. To save everything, on the Standard toolbar, click the Save All button Save All
  12. Return to the browser and refresh it
  13. Return to your programming environment

A Controller for a Directive

In previous sections, we saw that a directive can create its own isolate scope. If you use a module-based controller (a controller created using the controller() function) to send data to a view, you can (must) reconcile the isolate scope with the scope of the module controller. To do this, set the value of the controller property as a function. Here is an example of starting it:

angular.module('business', []).
    controller("LoanController", [function () {
    
            };
    }]).
    directive('personalLoan', function segmentizer() {
        return {
            . . .
            controller: function () {

            }
        };
    });

The function of the controller property takes one required and three optional arguments. The required first argument must specify the scope by which the directive will operate. You can pass that argument as a $scope object. In the body of the function, you can use the $scope service as you would use it in a module controller. That is, you can attach a property to it and assign a value to it. Here is an example:

var appTrafficSystem = angular.module("ticketing", []);

appTrafficSystem.directive('trafficSystem', function () {
    return {
        . . .
        controller: function ($scope) {
            $scope.mainTitle = 'Traffic Ticket System';
        }
    };
});

To specify how the $scoped value would be used in the directive, you can create a {{}} placeholder in the template property and include the $scoped value in it. Here is an example:

var appTrafficSystem = angular.module("ticketing", []);

appTrafficSystem.directive('trafficSystem', function () {
    return {
        restrict: "E",
        template: '<h1>{{mainTitle}}</h1>',
        controller: function ($scope) {
                $scope.mainTitle = 'Traffic Ticket System';
        }
    };
});

You can then use the directive. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Traffic Ticket System</title>
<script src="Scripts/angular.js"></script>
</head>
<body ng-app="ticketing">
<traffic-system></traffic-system>

<script type="text/javascript">
    var appTrafficSystem = angular.module("ticketing", []);

    appTrafficSystem.directive('trafficSystem', function () {
        return {
            restrict: "E",
            template: '<h1>{{mainTitle}}</h1>',
            controller: function ($scope) {
                $scope.mainTitle = 'Traffic Ticket System';
            }
        };
    });
</script>
</body>
</html>

A Controller for this Directive

Earlier, we saw that you can prepare a module controller for the value(s) that a custom directive. Remember that if you are not using a service, you can use the this object to create the value(s). Here are examples:

angular.module('trafficSystem', []).
    controller("TrafficController", function () {
        this.cameras = 'Traffic Cameras';
        this.drivers = 'Vehicle Operators';
        this.violations = 'Traffic Violations';
    }).
    directive('subTitle', function segmentizer() {
        return {
            restrict: "E",
            scope: { details: '=sectionTitle' },
            template: "<h2>{{details}}</h2>"
        };
    });

After creating the scope of a custom directive and the members of the of the controller, to apply the directive in the webpage, you must reconcile both scopes. To do this, you can use create an ng-controller attribute that has an instance of the controller. In the webpage, to access a member of the controller, precede it with the instance of the controller and a period. If you are using a directive, first create its element with its start and end tag. This would be done as follows:

<sub-title></sub-title>

In the start tag, add an attribute whose name is the value that was given to the scope property of the object of the directive. This would be done as follows:

<sub-title section-title></sub-title>

For the value of the attribute, use the instance of the controller and access the desired member of the controller. Here are example:

<!DOCTYPE html>
<html>
<head>
<style type="text/css">
h1            { border-bottom: 1px solid gray; }
.centered     { text-align:    center;         }
.row          { margin:        auto;
                width:         700px;
                display:       table;          }
.right-border { border-right:  1px solid gray; }
.column       { margin:        6px 6px 6px;
                float:         left;
                width:         33.3333%;       }
</style>
<meta charset="utf-8" />
<title>Traffic Ticket System</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body>
<script type="text/javascript">
    angular.module('trafficSystem', []).
        controller("TrafficController", function () {
            this.cameras = 'This is a description of the cameras used by our traffic system, including how they operate.';
            this.drivers = 'Here is a general introduction and information that vehicle operators should know.';
            this.violations = 'Take a look at how traffic violations function, are anlyzed, and are issued.';
        }).
        directive('subTitle', function segmentizer() {
            return {
                restrict: "E",
                scope: { details: '=sectionTitle' },
                template: "<p>{{details}}</p>"
            };
        });
</script>

<h1 class="centered">Traffic Ticket System</h1>

<div class="row" ng-app="trafficSystem" ng-controller="TrafficController as tc">
    <div class="column right-border">
        <sub-title section-title="tc.cameras"></sub-title>
    </div>
    <div class="column right-border">
        <sub-title section-title="tc.drivers"></sub-title>
    </div>
    <div>
        <sub-title section-title="tc.violations"></sub-title>
    </div>
</div>
</body>
</html>

This would produce:

Introducing Interfaces

An Isolate Scope for a Directive

In our introduction to controllers, we saw that you can use one or more controllers in a webpage. The primary job of a controller is to specify its area of influence. When creating a controller, one way you can specify the value(s) that would be used in its area or influence, its scope, is to attach one or more members (properties, functions, arrays, or objects, etc) to the $scope (or the $rootScope) service in the constructor of the controller. Here is an example:

angular.module('business', []).
    controller("LoanController", ['$scope', function ($scope) {
        $scope.review = "After a thorough review of your loan request, . . .";
    }]);

An isolate scope is a scope that is separate from the scope of a controller. As we have done so far, you can create such an isolate scope for a directive. Here is an example:

angular.module('business', []).
    controller("LoanController", ['$scope', function ($scope) {
        $scope.review = "After a thorough review and examination of your loan request, we don't have a choice but to deny it.";
    }]).
    directive('personalLoan', function segmentizer() {
        return {
            restrict: "E",
            scope: { applicant: '=loanRequest' },
            template: "<p>{{applicant}}</p>"
        };
    });

You will then reconcile that isolate scope with the $scope service of the controller in which the directive is used.

In the webpage, first create an ng-controller attribute using its name. Then, in the start tag of the directive, add an attribute that uses the value of the directive's scope object. In the document, access the member of the controller's $scope directly by its name. Here is an example:

<!DOCTYPE html>
<html>
<head>
<style type="text/css">
h1        { border-bottom: 1px solid gray; }
.centered { text-align:    center;         }
.contents { margin:        auto;
            width:         500px;
            display:       table;          }
</style>
<meta charset="utf-8" />
<title>Watts' A Loan</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body>
<script type="text/javascript">
    angular.module('business', []).
        controller("LoanController", ['$scope', function ($scope) {
            $scope.review = "After a thorough review and examination of your loan request, we don't have a choice but to deny it.";
        }]).
        directive('personalLoan', function segmentizer() {
            return {
                restrict: "E",
                scope: { applicant: '=loanRequest' },
                template: "<p>{{applicant}}</p>"
            };
        });
</script>
    <h1 class="centered">Watts' A Loan</h1>

    <div class="contents" ng-app="business" ng-controller="LoanController">
        <personal-loan loan-request="review"></personal-loan>
    </div>
</body>
</html>

This would produce:

A Scope for a Directive

A Scoped Object

As you may know already, the value(s) that a controller sends to a view can in fact be an object. To prepare the object in the controller, if you are using a service, attach a property name to the this object and assign a defined object to that property. Here is an example:

angular.module('trafficSystem', []).
    controller("TrafficController", function () {
        this.cameras = {
            title: 'Traffic Cameras',
            description: 'This is a description of the cameras used by our traffic system, including how they operate.'
        };
    });

In this case, to access a member of the this object in the directive, in the value of the template property, in its {{}} placeholder, type the name of the directive's scope property, a period, and the desired member of the controller's this object. In the webpage (the view), use the instance of the controoller and access the object of the controller. Here is an example:

<!DOCTYPE html>
<html>
<head>
<style type="text/css">
h1            { border-bottom: 1px solid gray; }
.centered     { text-align:    center;         }
.row          { margin:        auto;
                width:         700px;
                display:       table;          }
.right-border { border-right:  1px solid gray; }
.column       { margin:        6px 6px 6px;
                float:         left;
                width:         33.3333%;       }
</style>
<meta charset="utf-8" />
<title>Traffic Ticket System</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body>
<script type="text/javascript">
    angular.module('trafficSystem', []).
        controller("TrafficController", function () {
            this.cameras = {
                title: 'Traffic Cameras',
                description: 'This is a description of the cameras used by our traffic system, including how they operate.'
            };
            this.drivers = {
                title: 'Vehicle Operators',
                description: 'Here is a general introduction and information that vehicle operators should know.'
            };
            this.violations = {
                title: 'Traffic Violations',
                description: 'Take a look at how traffic violations function, are anlyzed, and are issued.'
            };
        }).
        directive('subTitle', function segmentizer() {
            return {
                restrict: "E",
                scope: { details: '=sectionTopic' },
                template: "<h2>{{ details.title }}</h2>" +
                          "<p>{{ details.description }}</p>"
            };
        });
</script>

<h1 class="centered">Traffic Ticket System</h1>

<div class="row" ng-app="trafficSystem" ng-controller="TrafficController as tc">
    <div class="column right-border">
        <sub-title section-topic="tc.cameras"></sub-title>
    </div>
    <div class="column right-border">
        <sub-title section-topic="tc.drivers"></sub-title>
    </div>
    <div>
        <sub-title section-topic="tc.violations"></sub-title>
    </div>
</div>
</body>
</html>

This would produce:

Introducing Interfaces

In the same way, if you are using a service, in the controller, assign an object {} to a $scope object and create the desired members in it. In the value of the template property use the value of the scope property, a period, and the desired member of the $scope object of the controller. In the webpage, set the value of the attribute of the directive to the name of the object that was attached to the $scope object. Here is an example:

<!DOCTYPE html>
<html>
<head>
<style type="text/css">
h1        { border-bottom: 1px solid gray; }
.centered { text-align:    center;         }
.contents { margin:        auto;
            width:         500px;
            display:       table;          }
</style>
<meta charset="utf-8" />
<title>Watts' A Loan</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body>
<script type="text/javascript">
    angular.module('business', []).
        controller("LoanController", ['$scope', function ($scope) {
            $scope.review = {
                typeOfLoan: "Personal Loan",
                amount: 6500,
                conclusion: "After a thorough review and examination of your loan request, we don't have a choice but to deny it."
            };
        }]).
        directive('personalLoan', function segmentizer() {
            return {
                restrict: "E",
                scope: { applicant: '=loanRequest' },
                template: "<h2>Type of Loan: {{ applicant.typeOfLoan }}</h2>" +
                          "<h3>Loan Amount: {{ applicant.amount }}</h3><p>Response: {{ applicant.conclusion }}</p>"
            };
        });
</script>

<h1 class="centered">Watts' A Loan</h1>

<div class="contents" ng-app="business" ng-controller="LoanController">
    <personal-loan loan-request="review"></personal-loan>
</div>
</body>
</html>

This would produce:

A Scope for a Directive

Practical LearningPractical Learning: Creating a Scoped Directive

  1. Change the TrafficTicketsSystem.js document as follows:
    var appTicketSystem = angular.module('TrafficTicketsSystem', []);
    
    appTicketSystem.directive('mainTitle', function () {
        return {
            restrict: "E",
            template: "<h2 class='topic-title common-font text-center bold'>Drivers/Owners Related Issues</h2>"
        };
    });
    
    appTicketSystem.controller('TicketsSystemController', ['$scope', function ($scope) {
        $scope.violations = {
            title: 'Traffic Violations',
            introduction: "Introduction: Our traffic ticket system considers various types of violations including driving through a Stop Sign, speeding, driving through a red light, etc.",
            stop: "Stop Sign: When coming to a Stop Sign, a vehicle operator is required to stop completely regardless of anything else going on.",
            speed : "Speed Limit: In most streets and roads of our county, speed limit signs are clearing posted. Except for emergency vehicles, every car is required to obey those speed limits.",
            red : "Red Light: A red light is probably the highest signal of a dangerous situation. When coming to a traffic signal that has a red light, whether steady or blinking, the vehicle must completely stop."
        };
    
        $scope.cameras = {
            title: 'Traffic Cameras',
            introduction: "Introduction: Our traffic ticket system uses the most precise and accurate cameras on the markets. They use the latest technologies and image development in terms of speed and resolution.",
            speed : "Cameras Features: Our cameras take their pictures and videos in the fractional time it take regular cameras to act. For all red light and Stop Sign violations, we provide pictures and videos to meet the highest demanding requirements.",
            demonstrations: "Demonstrations: We have various demonstrations of our cameras on our Web site. We also regularly conduct public demonstrations for various stakeholders. If you are interested in taking part of one of our demonstrations, please contact us to set up an appointment. The demonstration can be performed for an individual's interest or for a group."
        };
    
        $scope.drivers = {
            title: 'Vehicle Operators',
            description: "Description: Our primary goal in this county is to have safe, concerned, comfortable, but especially responsible drivers. We have street signs everywhere to keep you alert. While our roads provide you with convenient ways to move around the county, we also urge our drivers and multiple vehicle operators to be considerate not only of their environment and surrounding but also of other people whether they are pedestrians our are also driving. Consider that the roads are yours to share.",
            contact: "Contact Us: If you have any issue or concerns about our traffic cameras or the traffic ticketing system, please don't hesitate to contact us. You can contact us individually, as a group, as an organization, or by an authority of your choice, by phone, email, a form on our Web site, or a mailed letter."
        };
    }]);
    
    appTicketSystem.directive('subTitle', function () {
        return {
            restrict: 'E',
            scope: { topic: '=trafficSection' },
            template: "<h2 class='bold sub-title common-font blue'>{{ topic.title }}</h2>" +
                      "<p>{{ topic.introduction }}</p>" +
                      "<p>{{ topic.stop }}</p>" +
                      "<p>{{ topic.speed }}</p>" +
                      "<p>{{ topic.demonstrations }}</p>" +
                      "<p>{{ topic.description }}</p>" +
                      "<p>{{ topic.contact }}</p>" +
                      "<p>{{ topic.red }}</p>"
        };
    });
  2. Access the DriversIssues.cshtml document and change it as follows:
    @{
        ViewBag.Title = "Drivers/Owners Related Issues";
    }
    
    @Scripts.Render("~/bundles/jquery")
    
    <div ng-app="ticketSystem">
        <main-title></main-title>
    
        <div class="row common-font" ng-controller="TicketsSystemController">
            <div class="col-md-4">
                <sub-title traffic-section="violations"></sub-title>
            </div>
            <div class="col-md-4 left-right-border">
                <sub-title traffic-section="cameras"></sub-title>
            </div>
            <div class="col-md-4">
                <sub-title traffic-section="drivers"></sub-title>
            </div>
        </div>
    </div>
  3. To save everything, on the Standard toolbar, click the Save All button Save All
  4. Return to the browser and refresh it:

    Creating a Scoped Directive

  5. Close the browser and return to your programming environment

A Controller for Various Directives

In an AngularJS application, you can create a different controller for each directive, or you can create a controller that is shared by different directives.

Practical LearningPractical Learning: Introducing Directive Control

  1. On the main menu of Microsoft Visual Studio, click File -> New -> Project...
  2. In the middle list, click ASP.NET Web Application (.NET Framework) and set the project Name to TrafficTicketsSystem3
  3. Click OK
  4. In the New ASP.NET Web Application dialog box, click the MVC icon and click OK
  5. In the Solution Explorer, right-click TrafficTicketsSystem3 and click Manage NuGet Packages...
  6. In the NuGet tab, click Browser and, in the text box, type angularjs
  7. In the list, click angularjs
  8. Click Install.
    If a message box displays, click OK
  9. In the Solution Explorer, right-click Content -> Add -> Style Sheet
  10. Type TrafficTicketsSystem
  11. Click OK
  12. Create some styles as follows:
    body {
        background-color: #FFFFFF;
    }
    
    .bold              { font-weight:    600;               }
    .blue              { color:          #0d3bcf;           }
    .left-right-border { border-left:    1px solid gray;
                         border-right:   1px solid gray;    }
    .top-border        { border-top:     1px solid #0d3bcf;
                         padding-top:    1.05em;            }
    .topic-title       { color:          maroon;
                         padding-bottom: 0.25em;
                         border-bottom:  1px solid gray;    }
    .common-font       { font-family: Georgia, Garamond, 'Times New Roman', serif; }
  13. In the Solution Explorer, right-click Scripts -> Add > JavaScript File
  14. Type TrafficTicketsSystem as the name of the file
  15. Click OK
  16. In the document, type the following code:
    var appTicketSystem = angular.module('TrafficTicketsSystem', []);
    
    appTicketSystem.directive('mainTitle', function () {
        var ticket = {
            restrict: "E",
            template: "<h2 class='topic-title common-font text-center bold'>Drivers/Owners Related Issues</h2>"
        };
    
        return ticket;
    });
  17. In the Solution Explorer, right-click Scripts -> Add > JavaScript File
  18. Type TicketsSystemController as the name of the file
  19. Click OK
  20. In the document, type the following code:
    appTicketSystem.controller('TicketsSystemController', ['$scope', function ($scope) {
        $scope.violations = {
            title: 'Traffic Violations',
            introduction: "Our traffic ticket system considers various types of violations including driving through a Stop Sign, speeding, driving through a red light, etc.",
            stop: "When coming to a Stop Sign, a vehicle operator is required to stop completely regardless of anything else going on.",
            speed: "In most streets and roads of our county, speed limit signs are clearing posted. Except for emergency vehicles, every car is required to obey those speed limits.",
            red: "A red light is probably the highest signal of a dangerous situation. When coming to a traffic signal that has a red light, whether steady or blinking, the vehicle must completely stop."
        };
    
        $scope.cameras = {
            title: 'Traffic Cameras',
            introduction: "Our traffic ticket system uses the most precise and accurate cameras on the markets. They use the latest technologies and image development in terms of speed and resolution.",
            features: "Our cameras take their pictures and videos in the fractional time it take regular cameras to act. For all red light and Stop Sign violations, we provide pictures and videos to meet the highest demanding requirements.",
            demonstrations: "We have various demonstrations of our cameras on our Web site. We also regularly conduct public demonstrations for various stakeholders. If you are interested in taking part of one of our demonstrations, please contact us to set up an appointment. The demonstration can be performed for an individual's interest or for a group."
        };
    
        $scope.drivers = {
            title: 'Vehicle Operators',
            description: "Our primary goal in this county is to have safe, concerned, comfortable, but especially responsible drivers. We have street signs everywhere to keep you alert. While our roads provide you with convenient ways to move around the county, we also urge our drivers and multiple vehicle operators to be considerate not only of their environment and surrounding but also of other people whether they are pedestrians our are also driving. Consider that the roads are yours to share.",
            contact: "If you have any issue or concerns about our traffic cameras or the traffic ticketing system, please don't hesitate to contact us. You can contact us individually, as a group, as an organization, or by an authority of your choice, by phone, email, a form on our Web site, or a mailed letter."
        };
    }]);
  21. In the Solution Explorer, right-click Scripts -> Add > JavaScript File
  22. Type Violations as the name of the file
  23. Click OK
  24. In the document, type the following code:
    appTicketSystem.directive('violationsDescriptions', function () {
        return {
            restrict: 'E',
            template: "<h2 class='bold sub-title common-font blue'>{{ violations.title }}</h2>" +
            "<p><span class='bold'>Overview:</span> {{ violations.introduction }}</p>" +
            "<p><span class='bold'>Stop Sign:</span> {{ violations.stop }}</p>" +
            "<p><span class='bold'>Speed Limit:</span> {{ violations.speed }}</p>" +
            "<p><span class='bold'>Red Light:</span> {{ violations.red }}</p>"
        };
    });
  25. In the Solution Explorer, right-click Scripts -> Add > JavaScript File
  26. Type Cameras as the name of the file
  27. Click OK
  28. In the document, type the following code:
    appTicketSystem.directive('camerasTopics', function () {
        return {
            restrict: 'E',
            template: "<h2 class='bold sub-title common-font blue'>{{ cameras.title }}</h2>" +
                      "<p><span class='bold'>Overview:</span> {{ cameras.introduction }}</p>" +
                      "<p><span class='bold'>Cameras Features:</span> {{ cameras.features }}</p>" + 
                      "<p><span class='bold'>Demonstrations:</span> {{ cameras.demonstrations }}</p>"
        };
    });
  29. In the Solution Explorer, right-click Scripts -> Add > JavaScript File
  30. Type Drivers as the name of the file
  31. Click OK
  32. In the document, type the following code:
    appTicketSystem.directive('driversConcerns', function () {
        return {
            restrict: 'E',
            template: "<h2 class='bold sub-title common-font blue'>{{ drivers.title }}</h2>" +
                      "<p><span class='bold'>Description:</span> {{ drivers.description }}</p>" +
                      "<p><span class='bold'>Contact Us:</span> {{ drivers.contact }}</p>"
        };
    });
  33. In the Solution Explorer, expand App_Start and double-click BundleConfig.cs
  34. Change the document as follows:
    using System.Web;
    using System.Web.Optimization;
    
    namespace TrafficTicketsSystem3
    {
        public class BundleConfig
        {
            // For more information on bundling, visit https://go.microsoft.com/fwlink/?LinkId=301862
            public static void RegisterBundles(BundleCollection bundles)
            {
                bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                            "~/Scripts/jquery-{version}.js",
                            "~/Scripts/angular.js",
                            "~/Scripts/TrafficTicketsSystem.js",
                            "~/Scripts/TicketsSystemController.js",
                            "~/Scripts/Violations.js",
                            "~/Scripts/Cameras.js",
                            "~/Scripts/Drivers.js"));
    
                bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                            "~/Scripts/jquery.validate*"));
    
                // Use the development version of Modernizr to develop with and learn from. Then, when you're
                // ready for production, use the build tool at https://modernizr.com to pick only the tests you need.
                bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
                            "~/Scripts/modernizr-*"));
    
                bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
                          "~/Scripts/bootstrap.js",
                          "~/Scripts/respond.js"));
    
                bundles.Add(new StyleBundle("~/Content/css").Include(
                          "~/Content/bootstrap.css",
                          "~/Content/site.css",
                          "~/Content/TrafficTicketsSystem.css"));
            }
        }
    }
  35. In the Solution Explorer, expand Controllers and double-click HomeController.cs
  36. Create an action method named DriversIssues
    using System.Web.Mvc;
    
    namespace TrafficTicketsSystem3.Controllers
    {
        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                return View();
            }
    
            public ActionResult About()
            {
                ViewBag.Message = "We are in charge of issuing traffic tickets, management them, and collecting their payments.";
    
                return View();
            }
    
            public ActionResult Contact()
            {
                ViewBag.Message = "Let us know any type of concern or issue that crosses your mind.";
    
                return View();
            }
    
            public ActionResult DriversIssues()
            {
                return View();
            }
        }
    }
  37. In the document, right-click DriversIssues and click Add View...
  38. In the Add View dialog box, make sure the View Name text box displays DriversIssues. Click Add
  39. Change the document as follows:
    @{
        ViewBag.Title = "Drivers/Owners Related Issues";
    }
    
    @Scripts.Render("~/bundles/jquery")
    
    <div ng-app="TrafficTicketsSystem">
        <main-title></main-title>
    
        <div class="common-font" ng-controller="TicketsSystemController">
            <div class="col-md-4">
                <violations-descriptions></violations-descriptions>
            </div>
            <div class="col-md-4 left-right-border">
                <cameras-topics></cameras-topics>
            </div>
            <div class="col-md-4">
                <drivers-concerns></drivers-concerns>
            </div>
        </div>
    </div>
  40. To execute the application, on the main menu, click Debug and click Start Without Debugging

    Creating a Scoped Directive

  41. Return to your programming environment

A Web File for a Template

The AngularJS documentation recommends that if the template for a directive consists of more that a simple line of code or a single line, you should put the result of the directive in its own Webpage. You can then access the directive using its URL and add it to the desired section of a common webpage. We already know that, to do that, you must add a templateUrl property to the directive.

Practical LearningPractical Learning: Creating a Wep Page for each Directive

  1. In the Solution Explorer, right-click TrafficTicketsSystem3 -> Add -> New Folder
  2. Type DriversIssues
  3. In the Solution Explorer, right-click DriversIssues -> Add -> HTML Page
  4. Type Violations as the name of the file
  5. Click OK
  6. Replace the content of the document with:
    <h2 class="bold sub-title common-font blue">{{ violations.title }}</h2>
    <p><span class="bold">Overview:</span> {{ violations.introduction }}</p>
    <p><span class="bold">Stop Sign:</span> {{ violations.stop }}</p>
    <p><span class="bold">Speed Limit:</span> {{ violations.speed }}</p>
    <p><span class="bold">Red Light:</span> {{ violations.red }}</p>
  7. In the Solution Explorer, right-click DriversIssues -> Add -> HTML Page
  8. Type Cameras
  9. Click OK
  10. Replace the content of the document with:
    <h2 class="bold sub-title common-font blue">{{ cameras.title }}</h2>
    <p><span class="bold">Overview:</span> {{ cameras.introduction }}</p>
    <p><span class="bold">Cameras Features:</span> {{ cameras.features }}</p>
    <p><span class="bold">Demonstrations:</span> {{ cameras.demonstrations }}</p>
  11. In the Solution Explorer, right-click DriversIssues -> Add -> HTML Page
  12. Type Drivers
  13. Click OK
  14. Replace the content of the document with:
    <h2 class="bold sub-title common-font blue">{{ drivers.title }}</h2>
    <p><span class="bold">Description:</span> {{ drivers.description }}</p>
    <p><span class="bold">Contact Us:</span> {{ drivers.contact }}</p>
  15. Access the Violations.js file and change it as follows:
    appTicketSystem.directive('violationsDescriptions', function () {
        return {
            restrict: 'E',
            templateUrl: "/DriversIssues/Violations.html"
        };
    });
  16. Access the Cameras.js file and change it as follows:
    appTicketSystem.directive('camerasTopics', function () {
        return {
            restrict: 'E',
            templateUrl: "/DriversIssues/Cameras.html"
        };
    });
  17. Access the Drivers.js file and change it as follows:
    appTicketSystem.directive('driversConcerns', function () {
        return {
            restrict: 'E',
            templateUrl: "/DriversIssues/Drivers.html"
        };
    });
  18. To save everything, on the Standard toolbar, click the Save All button Save All
  19. Return to the browser and refresh it
  20. Close the browser and return to your programming environment

A Common Name for an Isolate Scope and Value

When creating the scope in the object returned by the directive, if the value you want to use for the scope property is the same as the name of the property, you can omit that value. That is, set the value of the property as = in quotes. Here are examples:

<!DOCTYPE html>
<html>
<head>
<style type="text/css">
h1            { border-bottom: 1px solid gray; }
.centered     { text-align:    center;         }
.row          { margin:        auto;
                width:         700px;
                display:       table;          }
.right-border { border-right:  1px solid gray; }
.column       { margin:        6px 6px 6px;
                float:         left;
                width:         33.3333%;       }
</style>
<meta charset="utf-8" />
<title>Traffic Ticket System</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body>
<script type="text/javascript">
    angular.module('trafficSystem', []).
        controller("TrafficController", function () {
            this.cameras = 'This is a description of the cameras used by our traffic system, including how they operate.';
            this.drivers = 'Here is a general introduction and information that vehicle operators should know.';
            this.violations = 'Take a look at how traffic violations function, are anlyzed, and are issued.';
        }).
        directive('subTitle', function segmentizer() {
            return {
                restrict: "E",
                scope: { details: '=' },
                template: "<p>{{details}}</p>"
            };
        });
</script>

<h1 class="centered">Traffic Ticket System</h1>

<div class="row" ng-app="trafficSystem" ng-controller="TrafficController as tc">
    <div class="column right-border">
        <sub-title details="tc.cameras"></sub-title>
    </div>
    <div class="column right-border">
        <sub-title details="tc.drivers"></sub-title>
    </div>
    <div>
        <sub-title details="tc.violations"></sub-title>
    </div>
</div>
</body>
</html>

Practical LearningPractical Learning: Ending the Lesson


Previous Copyright © 2017-2022, FunctionX Next