Controlling a Directive
Controlling a Directive
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 Learning: Introducing Directive Control
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; }
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."; }]);
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")); } } }
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();
}
}
}
@{
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>
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 Learning: Using an Instance of a Controller
. . . 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>"
};
});
. . . No Change
<body>
<p>Take a look at how traffic violations function, are anlyzed, and are issued.</p>
<violations-topics></violations-topics>
</body>
</html>
<!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">© @DateTime.Now.Year - Traffic Ticket System</p> </div> @Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/bootstrap") @RenderSection("scripts", required: false) </body> </html>
. . .
<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>
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>" }; });
. . . No Change
<body>
<violations-topics></violations-topics>
</body>
</html>
@{ 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>
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 Learning: Using the Scope Service for a Controller
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>" }; });
. . . No Change
<body>
<drivers-concerns></drivers-concerns>
</body>
</html>
. . . No Change
<body>
<cameras-issues></cameras-issues>
</body>
</html>
@{ 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>
. . . 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>" }; });
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:
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 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:
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:
Practical Learning: Creating a Scoped Directive
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>" }; });
@{ 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>
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 Learning: Introducing Directive Control
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; }
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; });
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." }; }]);
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>" }; });
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>" }; });
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>" }; });
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")); } } }
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();
}
}
}
@{
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>
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 Learning: Creating a Wep Page for each Directive
<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>
<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>
<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>
appTicketSystem.directive('violationsDescriptions', function () { return { restrict: 'E', templateUrl: "/DriversIssues/Violations.html" }; });
appTicketSystem.directive('camerasTopics', function () { return { restrict: 'E', templateUrl: "/DriversIssues/Cameras.html" }; });
appTicketSystem.directive('driversConcerns', function () { return { restrict: 'E', templateUrl: "/DriversIssues/Drivers.html" }; });
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 Learning: Ending the Lesson
|
||
Previous | Copyright © 2017-2022, FunctionX | Next |
|