Fundamentals of Directives

Introduction

An AngularJS directive is an object that indicates how an HTML tag, an element's attribute, or a style (or a webpage comment) should appear or behave on a webpage. As you may know already, AngularJS ships with many read-made directives. Some of the directives are ng-app, ng-controller, ng-model, ng-init, ng-repeat, ng-click, etc.

Practical LearningPractical Learning: Introducing Directives

  1. Start Microsoft Visual Studio
  2. On the main menu of Microsoft Visual Studio, click File -> New -> Project...
  3. In the central list, click ASP.NET Web Application (.NET Framework).
    Change the project Name to TrafficTicketsManagement1
  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 TrafficTicketsManagement1 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 TrafficTicketsManagement1 -> Add -> New Folder
  11. Type Presentations
  12. In the Solution Explorer, right-click Content -> Add -> Style Sheet
  13. Type TrafficTicketsSystem
  14. Click OK
  15. 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; }
    
  16. In the Solution Explorer, expand App_Start and double-click BundleConfig.cs
  17. Change the document as follows:
    using System.Web;
    using System.Web.Optimization;
    
    namespace TrafficTicketsManagement1
    {
        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.min.js"));
    
                // 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"));
            }
        }
    }
  18. In the Solution Explorer, expand Controllers and double-click HomeController.cs
  19. Create an action method named Presentations
    using System.Web.Mvc;
    
    namespace TrafficTicketsManagement1.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 Presentations() => View();
        }
    }
  20. In the document, right-click Presentations() and click Add View...
  21. In the Add View dialog box, make sure the View Name text box displays Presentations. Click Add
  22. In the Solution Explorer, under Views, expand Shared and double-click _Layout.cshtml
  23. 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("Services Topics", "Presentations", "Home", new { area = "" }, null)</li>
                        <li>@Html.ActionLink("About TTS", "About", "Home")</li>
                        <li>@Html.ActionLink("Contact Us", "Contact", "Home")</li>
                    </ul>
                </div>
            </div>
        </div>
        <div class="container body-content">
            @RenderBody()
            <footer>
                <p class="text-center common-font">&copy; @DateTime.Now.Year - Traffic Tickets System</p>
            </footer>
        </div>
    
        @Scripts.Render("~/bundles/jquery")
        @Scripts.Render("~/bundles/bootstrap")
        @RenderSection("scripts", required: false)
    </body>
    </html>

Templates

An AngularJS template is an HTML tag or section of a webpage that contains AngularJS code such as a directive, a markup placeholder {{}}, etc.

Starting a Directive

Besides using AngularJS built-in directives, you can create your own custom directives. This allows you to create sections of code to display something the way you want.

A directive is created with a function named directive. As is the case for the other components, to register a directive, you can attach the directive() function to the creation of another component, such as a module. This can be done as follows:

angular.module("ticketSystem", []).directive(. . .)

You can also attach the directive() function to the creation of a controller. Here is an example:

var appTicketSystem = angular.module("ticketSystem", []);

appTicketSystem.controller('TicketsController', function () {

}).directive(. . .);

You can also attach a directive() function to a module variable. This can be done as follows:

var appTicketSystem = angular.module("ticketSystem", []);

appTicketSystem.directive(. . .). . .

Like every component, a directive must have a name. Here is an example:

var appBinaryDiagnosis = angular.module("binaryDiagnosis", []);

appBinaryDiagnosis.directive("purpose"). . .

A Constructor for a Directive

As is the case for the other components, the job of a custom directive is carried by a function as its constructor. That function is passed as the second argument to the directive() function. Once again, you can first create a function and pass its name as the second argument to the directive() function. Here is an example:

var appBinaryDiagnosis = angular.module("binaryDiagnosis", []);
    
function predict() {
        
}
appTicketSystem.directive('position', predict);

Or you can define the function argument directly in the placeholder of the second argument to the directive() function. Here is an example:

var appBinaryDiagnosis = angular.module("binaryDiagnosis", []);
    
appBinaryDiagnosis.directive('position', function() {

});

Introduction to Using a Directive

After creating a directive, you can use it as an HTML element. Here is an example:

. . .
<body ng-app="waterDistribution">
    <purpose></purpose>
<script type="text/javascript">
    var appWater = angular.module("ticketSystem", []);

    appWater.directive("purpose", function() {

    })
</script>
</body>
</html>

The Name of a Directive

Unlike the other components, the name of a directive must follow some rules. When you create a directive, its name must use the camelCase: the name must be in one word with the first letter in lowercase and each subsequent word must start in uppercase. Here are examples:

var app = angular.module("sportBusiness", []);

app.directive("serious", function() {

});
app.directive("fairPlay", function() {

});
app.directive("makeItReal", function() {

});

If the name of your directive is made of more than one word, avoid starting it with ng, NG, or nG because this could cause conflicts or confusions with AngularJS built-in directives.

Using a Custom Directive

When applying a directive, the name is used as follows. If the name is in one word, simply use it as done previously. If the name is made of many words, after the first word, each subsequent word must be separated from the previous with a dash and must be converted to lowercase. Here are examples:

<body ng-app="waterDistribution">
    <fair-play></fair-play>
    <parallel-operating-system></parallel-operating-system>
<script type="text/javascript">
    var appWater = angular.module("waterDistribution", []);

    appWater.directive("fairPlay", function() {

    });
    appWater.directive("parallelOperatingSystem", function() {

    });
</script>

In the same way, in AngularJS, a built-in directive is created from a camelCase-name object. When the directive is applied, it uses (a) dash(es) in its name. Examples of the objects are ngModel for the ng-model directive, ngBind for the ng-bind directive, ngCliclk for the ng-click event, etc.

Introductory Characteristics of a Directive

An Object for a Directive

As mentioned already, the job of a directive is carried by a function that is the second argument to the directive() function. The function of a directive must return an object that indicates what the directive should display or how it should behave. You can first create an object and return it in the function. Here is an example:

var diagnoses = {

};

var appTicketSystem = angular.module("ticketSystem", []);
    
appTicketSystem.directive('position', function() {
        return diagnoses;
});

Or create the object directly after the return keyword. Here is an example:

var appTicketSystem = angular.module("ticketSystem", []);
    
appTicketSystem.directive('position', function() {
    return {
            
    };
});

A Template for a Directive

In most cases, a directive is meant to display something, such as text, etc. To create the content of a directive, add a property named template. If you want the directive to display text, set that text as the value of the template property. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Exercise</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="binaryDiagnosis">
<position></position>

<script type="text/javascript">
    var diagnoses = {
        template: "What was supposed to happen happened."
    };

    var appBinaryDiagnosis = angular.module("binaryDiagnosis", []);
    
    appBinaryDiagnosis.directive('position', function() {
        return diagnoses;
    });
</script>
</body>
</html>

A Template for a Directive

If the value is a long string, you can segment it using the addition operator applied to a string. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Exercise</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="diagnosis">
    <lsn-diagnosis></lsn-diagnosis>

<script type="text/javascript">
    var diagnoses = {
        template: "What was supposed to happen happened. " +
                  "What was not supposed to happen did not happen."
    };

    var appBinaryDiagnosis = angular.module("binaryDiagnosis", []);

    appBinaryDiagnosis.directive('lsnDiagnosis', function() {
        return diagnoses;
    });
</script>
</body>
</html>

HTML Tags in a Directive

In the value of the template property, you can include HTML tags. Here are examples:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Exercise</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="diagnosis">
<lsn-diagnosis></lsn-diagnosis>

<script type="text/javascript">
    var diagnoses = {
        template: "<p>What <i>supposed</i> to happen happened.</p>"
    };

    var appBinaryDiagnosis = angular.module("binaryDiagnosis", []);
    
    appBinaryDiagnosis.directive('lsnDiagnosis', function() {
        return diagnoses;
    });
</script>
</body>
</html>

Formatting the Contents of a Directive

A directive can contain CSS formatting. Here are examples:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Exercise</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="binaryPropositions">
<lsn-diagnosis></lsn-diagnosis>

<script type="text/javascript">
    var diagnoses = {
        template: "<h1 style='color: maroon'>Proposition</h1><p>What was <span style='text-decoration: underline'>supposed</span> to happen happened.</p>"
    };

    var appBinaryPropositions = angular.module("binaryPropositions", []);
    
    appBinaryPropositions.directive('lsnDiagnosis', function() {
        return diagnoses;
    });
</script>
</body>
</html>

Practical LearningPractical Learning: Creating a Directive

  1. Click the Presentations.cshtml tab and change the document as follows:
    @{
        ViewBag.Title = "Traffic Management Topics";
    }
    
    @Scripts.Render("~/bundles/jquery")
    
    <div ng-app="TrafficTicketsSystem">
        <main-title></main-title>
    </div>
    
    <script type="text/javascript">
        var ticket = {
            template: "<h2 class='topic-title maroon common-font text-center bold'>Traffic Management Topics</h2>"
        };
        var appTicketSystem = angular.module('TrafficTicketsSystem', []);
    
        appTicketSystem.directive('mainTitle', function () {
            return ticket;
        });
    </script>
  2. To execute, on the main menu, click Debug -> Start Without Debugging:

    Creating a Directive

  3. Return to your programming environment

A Function for a Template

The value of the template property can come from a function. In this case, assign a function {} statement to the template property. In the body of the function, create the content and formatting you want the directive to display and return that string. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Exercise</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="diagnosis">
    <lsn-diagnosis></lsn-diagnosis>

<script type="text/javascript">
    var diagnoses = {
        template: function () {
            return "<p>What was <i>supposed</i> to happen happened.</p>";
        }
    };

    var appBinaryDiagnosis = angular.module("binaryDiagnosis", []);

    appBinaryDiagnosis.directive('lsnDiagnosis', function () {
        return diagnoses;
    });
</script>
</body>
</html>

A Directive with Markup

You can also include (a) {{}} placeholder(s), in which case you will supply the value(s) of the placeholder(s). This would be done as follows:

angular.module("diagnosis", []).directive('lsnDiagnosis', function() {
    return {
        template: "<ul>" +
                  "<li>{{ something }}</li>" +
                  "<li>{{ another }}</li>" +
                  "</ul>"
    };
});

These characteristics allow you to create the contents of a directive as complex as you want.

Intermediate Techniques of Using a Directive

A Directive as Element

There are various ways you can use a directive. As we have done so far, you can use a directive as its own HTML element. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Exercise</title>
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/Promotions.js"></script>
<style>
.container { margin:     auto;
             width:      500px; }
.centered  { text-align: center; }
</style>
</head>
<body ng-app="waterDistribution">
    <div class="container">
        <main-title></main-title>
    </div>
<script type="text/javascript">
    angular.module('waterDistribution', []).
        directive('mainTitle', function () {
            return {
				template: "<h1 class='centered'>Water Distribution Company</h1><h2 class='centered'>Water Meters</h2>" };
        })
</script>    
</body>
</html>

In the same way, you can use the same directive in many sections of the same webpage. 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; }
.col          { 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', []).directive('subTitle', function segmentizer() {
        return {
            template: "Traffic Management"
        }
    });
</script>
<h1 class="centered">Traffic Ticket System</h1>

<div class="row" ng-app="trafficSystem">
    <div class="col right-border">
        <sub-title></sub-title>
        <h4>Traffic Cameras</h4>
        <p>This is a description of the cameras used by our traffic system.</p>
    </div>
    <div class="col right-border">
        <sub-title></sub-title>
        <h4>Vehicle Operators</h4>
        <p>Here is a general introduction and information that vehicle operators should know.</p>
    </div>
    <div>
        <sub-title></sub-title>
        <h4>Traffic Violations</h4>
        <p>Take a look at how traffic violations function, are anlyzed, and are issued.</p>
    </div>
</div>
</body>
</html>

You can also use the same directive in different webpages.

In the above case, we assumed that the directive was defined with everything that is necessary for its functionality and there was nothing between the start and the end tags. Otherwise, you can add any content between the starting and the closing tags of the directive. You can also include a directive inside an HTML element. Here is an example:

<h3><sub-title></sub-title></h3>

ApplicationPractical Learning: Using the Same Directive Many Times

  1. Change the document as follows:
    @{
        ViewBag.Title = "Traffic Management Topics";
    }
    
    @Scripts.Render("~/bundles/jquery")
    
    <div ng-app="TrafficTicketsSystem">
        <main-title></main-title>
    
        <div class="row common-font">
            <div class="col-md-4">
                <sub-title></sub-title>
                <p>This is a description of the cameras used by our traffic system.</p>
            </div>
            <div class="col-md-4 left-right-border">
                <sub-title></sub-title>
                <p>Here is a general introduction and information that vehicle operators should know.</p>
            </div>
            <div class="col-md-4">
                <sub-title></sub-title>
                <p>Take a look at how traffic violations function, are anlyzed, and are issued.</p>
            </div>
        </div>
    </div>
    
    <script type="text/javascript">
        var ticket = {
            template: "<h2 class='topic-title maroon common-font text-center bold'>Traffic Tickets Management Topics</h2>"
        };
        var appTicketSystem = angular.module('TrafficTicketsSystem', []);
    
        appTicketSystem.directive('mainTitle', function () {
            return ticket;
        }).directive('subTitle', function () {
            return {
                template: "Traffic Management"
            }
        });
    </script>
  2. To save everything, on the Standard toolbar, click the Save All button Save All
  3. Return to the browser and refresh it (in most browsers, you can press F5, or right-click inside the webpage and click Reload)

    Creating a Directive

  4. Return to your programming environment

A Directive as an HTML Attribute

You can use a directive as an attribute to an HTML element. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Movies Titles</title>
<script src="Scripts/angular.min.js"></script>
</head>
<body ng-app="movies">
<h1>Movies Titles</h1>

<p vengeance></p>

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

    appDevelopment.directive('vengeance', function () {
        return {
            template: "<span style='text-transform: capitalize'>Vengeance is a dish served cold.</span>"
        };
    });
</script>
</body>
</html>

Here is an example: or the name of a class.

A Directive as an HTML Attribute

In this example, we only specified the name of the attribute. If necessary, you can create an attribute that would use an external value that you would then assign to the directive (we will see examples in the section on scopes). You can also assign empty double-quotes to the directives

You can also use a directive as the value of a CSS class (we will see an example below) or include it in an HTML comment.

Restricting the Use of a Directive

When creating a directive, you can restrict its use to one of the above manners and more. To do this, in the object of the directive, add a property named restrict and set its value as one of the following options that must be specified as a string:

A Web Page Portion for a Directive

A Web File for a Directive

A directive holds its own contents, such as its own text and formatting. This allows a directive to control its content independently of the other parts of a webpage. In fact, this characteristic makes it possible for the same directive to be used by many web pages so that, as we saw for the layout page in ASP.NET MVC, a directive can be shared among many webpages and, when the directive is changed, the section, and only that section, of the webpage where it is applied receives the same change.

To prepare a directive that would occupy a particular section of a webpage, create a file that defines the value of the template property of the directive. Normally, this is a regular HTML page. Here is an example of a file named Sales.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<p>This week only, all Florida oranges at 50%.</p>
</body>
</html>

For a directive, you need only the section that uses the part you will display.

Practical LearningPractical Learning: Creating Partial Templates

  1. In the Solution Explorer, right-click Presentations -> Add -> New Item...
  2. In the left frame, click Web and, in the middle frame, click HTML Page
  3. Change the Name of the file to Cameras
  4. Click OK
  5. In document, type a one-line paragraph as follows:
    . . . No Change
    <body>
    <p>This is a description of the cameras used by our traffic system, including how they operate.</p>
    </body>
    </html>
  6. In the Solution Explorer, right-click Presentations -> Add -> HTML Page
  7. Type Drivers as the name of the file
  8. Click OK
  9. In document, type a one-line paragraph as follows:
    . . . No Change
    <body>
    <p>Here is a general introduction and information that vehicle operators should know.</p>
    </body>
    </html>
  10. In the Solution Explorer, right-click TrafficManagement -> Add -> HTML Page
  11. Type TrafficViolations as the name of the file
  12. Click OK
  13. In document, type a one-line paragraph as follows:
    . . . No Change
    <body>
    <p>Take a look at how traffic violations function, are anlyzed, and are issued.</p>
    </body>
    </html>

A URL Template for a Directive

To indicate that the contents of a directive will come from a file, in the object of the directive, create a property named templateUrl. Set the value of this property as the name or path of of the file that uses the directive. Here is an example of a JavaScript file named Promotions.js:

var appSupermarket = angular.module("supermarket", []);

appSupermarket.directive('weeklyPromotions', function () {
    return {
        templateUrl: 'Sales.html'
    };
});

In the document that needs the directive, apply that directive as we saw already. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Seven-Corner Supermarket</title>
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/Promotions.js"></script>
</head>
<body ng-app="supermarket">
    <weekly-promotions></weekly-promotions>
</body>
</html>

In the same way, you can create different HTML files for various sections. You can make each HTML file for a different directive. For example, here is the contents of a file named Sales.html

<p>This week only, check the following once-in-a-lifetime sales:</p>
<ul>
    <li>Apples: $4.95/Bag</li>
    <li>Oranges: 50%</li>
    <li>Banana: 75%</li>
    <li>Home-made Cookies: $2.25</li>
</ul>

Here is an example of a file named Pharmacy.js

<h2>Our pharmacy is conducting Flu shots this week. Ask your cashier or one of our store associates for more information.</h2>

You can create each directive on its own file or you can create them in the same file. Here is an example of a file named Promotions.js

var appSupermarket = angular.module("supermarket", []);

appSupermarket.directive('weeklyPromotions', function () {
    return {
        templateUrl: 'Sales.html'
    };
});

appSupermarket.directive('pharmacyAds', function () {
    return {
        templateUrl: 'Pharmacy.html'
    };
});

In the main or central webpage, you can create a tag for each directive. Here are examples:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Seven-Corner Supermarket</title>
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/Promotions.js"></script>
<style>
body             { margin:           0;               }
.whole-width     { width:            100%;            }
.top-section     { margin-top:       0; 
                   background-color: #760303;
                   color:            azure;           }
.bottom-section  { margin-bottom:    0;
                   background-color: #3e0505;
                   color:            antiquewhite;    }
.pads            { padding:          1em;             }
.centered-text   { text-align:       center;          }
.container       { margin:           auto;
                   width:            1000px;
                   border:           1px solid gray;  }
.central-section { margin:           0;
                   max-width:        66%;             }
.weekly-ads      { margin-left:      66%;
                   border-left:      1px solid black; }
.cleft           { float:            left;            }
</style>
</head>
<body ng-app="supermarket">
    <div class="container">
        <header class="top-section cleft whole-width">
            <h1 class="centered-text">Seven-Corner Supermarket</h1>
            <h2 class="centered-text">Customer Order Processing</h2>
        </header>
        <div class="central-section pads">
            <table style="width: 100%">
                <tr>
                    <td><b>Item #</b></td>
                    <td><b>Unit Price</b></td>
                </tr>
            </table>
        </div>
        <div class="weekly-ads pads">
            <weekly-promotions></weekly-promotions>
        </div>

        <footer class="bottom-section cleft">
            <pharmacy-ads></pharmacy-ads>
        </footer>
    </div>
</body>
</html>

Practical LearningPractical Learning: Creating a Layout Template

  1. In the Solution Explorer, right-click Scripts -> Add -> JavaScript File
  2. Type TrafficTicketsSystem
  3. Press Enter
  4. In the empty document, type the following code:
    var appTicketSystem = angular.module('TrafficTicketsSystem', []);
    
    appTicketSystem.directive('mainTitle', function () {
        var ticket = {
            restrict: "E",
            template: "<h2 class='topic-title maroon common-font text-center bold'>Traffic Tickets Management Topics</h2>"
        };
    
        return ticket;
    });
    
    appTicketSystem.directive('camerasSummary', function () {
        return {
            restrict: "E",
            templateUrl: "/Presentations/Cameras.html"
        }
    });
    
    appTicketSystem.directive('vehicleOperators', function () {
        return {
            restrict: "E",
            templateUrl: "/Presentations/Drivers.html"
        }
    });
    
    appTicketSystem.directive('trafficViolations', function () {
        return {
            restrict: "E",
            templateUrl: "/Presentations/TrafficViolations.html"
        }
    });
  5. In the Solution Explorer, under App_Start, double-click BundleConfig.cs and change it as follows:
    using System.Web.Optimization;
    
    namespace TrafficTicketsManagement1
    {
        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"));
    
                // 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"));
            }
        }
    }
  6. Click the Presentations.cshtml tab to access the file
  7. Change the document as follows:
    @{
        ViewBag.Title = "Traffic Management Topics";
    }
    
    @Scripts.Render("~/bundles/angular")
    
    <div ng-app="TrafficTicketsSystem">
        <main-title></main-title>
    
        <div class="row common-font">
            <div class="col-md-4">
                <cameras-summary></cameras-summary>
            </div>
            <div class="col-md-4 left-right-border">
                <vehicle-operators></vehicle-operators>
            </div>
            <div class="col-md-4">
                <traffic-violations></traffic-violations>
            </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

    Creating a Directive

  10. Close the browser and return to your programming environment

The Scope of a Directive

Introduction

As you are probably aware already, in application programming, the area of code in which a value or object is available or "seen" is referred to as its scope. In AngularJS, a scope indicates the area where a directive will be used and the name by which the directive can be used in that scope.

To let you create a scope for a directive, the object returned by a directive is equipped with a property named scope. The value of that property is an object that uses one or more members. This means that, to create a scope, assign {} to the scope property.

In the body of the scope property, create a property that will hold the scope name of the directive. The name of that property can be any one-word name of your choice. That name can be in one or more words. If it is in one word, it must be in lowercase. If it is in many words, it must use the camelCase.

A Scope for a Web Address

If you want to use the directive as a link (Web address, email, etc), set the value of the property as @ in quotes. For the value of the template property, you can create text that contains a link. 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:         700px;
            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', []).
        directive('contactUs', function segmentizer() {
            return {
                scope: { something: '@' },
                template: "<a href='mailto:support@functionx.com'>To apply for a loan, please contact us.</a>"
            };
        });
</script>

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

<div class="contents" ng-app="business">
    <contact-us></contact-us>
</div>
</body>
</html>

If you want to provide the link as an attribute of your directive, create a {{}} placeholder in the value of the template property. Include the name of an @ property you had created in the scope object and put that name in that placeholder. When applying the directive, add an attribute to it. Use the name of the @ property of the scope object and assign the desired link to it. Here is an example:

<script type="text/javascript">
    angular.module('business', []).
        directive('contactUs', function segmentizer() {
            return {
                scope: { support: '@' },
                template: "<a href='{{support}}'>To apply for a loan, please contact us.</a>"
            };
        });
</script>

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

<div class="contents" ng-app="business">
    <contact-us support="mailto:support@functionx.com"></contact-us>
</div>

If you want to provide the text of the link as an attribute of your directive, add property for it in the scope object and assign an @ string to it. In the template property, create a {{}} placeholder for the text. Include the name of the @ property of the scope object in that placeholder. When applying the directive, add an attribute to it using the name of the @ property of the scope object and assign the desired text to it. 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:         700px;
            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', []).
        directive('contactUs', function segmentizer() {
            return {
                scope: {
                    loanApplication: '@',
                    instructions: '@'
                },
                template: "<a href='{{loanApplication}}'>{{instructions}}</a>"
            };
        });
</script>

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

<div class="contents" ng-app="business">
    <contact-us loan-application="www.functionx.com/loan_app.htm"
        instructions="To apply for a loan, please fill the form on the indicated webpage. Please provide as much information as possible."></contact-us>
</div>
</body>
</html>

A Scope for an HTML Attribute

To create a directive that will use an attribute in the code of the webpage. In this case, the attribute will use an object or value of a member of the controller. In this case, the value of the property must start with = followed by the name of the attribute that will be used in the start tag of the directive. Here is an example:

angular.module('trafficSystem', []).
    directive('subTitle', function segmentizer() {
            return {
                scope: { details: '=sectionTitle' }
    };
});

Once again, you must add a way for the directive to get (and display) its content. One way you can do this is to add a template property to the object returned by the directive. For the value of that property, you can create a {{}} placeholder. In that placeholder, include the name of the scope property. Here is an example:

angular.module('trafficSystem', []).
    directive('subTitle', function segmentizer() {
        return {
            scope: { details: '=sectionTitle' },
            template: "<h2>{{details}}</h2>"
        };
    });

If you want to indicate the type of directive, which is usually a good idea to make things clear and make sure the directive is used as intended, add a restrict property to the object and set the appropriate value. Here is an example:

angular.module('trafficSystem', []).
    directive('subTitle', function segmentizer() {
        return {
            restrict: "E",
            scope: { details: '=sectionTitle' },
            template: "<h2>{{details}}</h2>"
        };
    });

A Single-Page Application

Introduction

A single-page application, or SPA, is a website that uses a central webpage that serves as a hosting parent for other webpages. It works as follows. A central webpage is created. It contains one or more special sections. Other webpages are created in the same folder as the central webpage or in other folders. When a webpage is requested, such as if a visitor clicks a link, the content of that webpage displays in a reserved section of the central webpage. It appears as if the user is using only one webpage but behind-the-scenes, when something is requested, the webserver sends the necessary content and it displays in the reserved section of the central webpage. As a result, when something is requested, only the necessary section of the central webpage is updated and there is no reason to reload the whole webpage or to refresh it entirely.

Both ASP.NET and AngularJS support single-page applications, each in its own way.

ASP.NET and Single-Page Applications

When it comes to ASP.NET MVC, we already know that you can first create a layout page as a central document and call the RenderBody() method in it. When a webpage is requested, its content would then display in that RenderBody() placeholder. That technique is just the beginning. There are other features that can be used.

Embedding Web Pages in a Document in AngularJS

Introduction to the Include Directive

As we saw in the previous sections, AngularJS fully supports single-page applications through directives and other options. Additionally, AngularJS allows you to include a webpage in the body of another webpage. This is done using a directive named ng-inlcude.

Before using the ng-inlcude directive, you should create the webpage(s) you will need. You should plan to (create and) use only the webpages of the same project or website.

After creating the webpage(s), create an AngularJS controller. In its function, attach a variable to a $scope service or a this object. Assign the name or path of the target webpage as a string. Here is an example:

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

app.controller('CountryController', [function () {
    this.state = 'Government.html';
}]);

If you are planning to use many files, you can attach a variable for each or create an array of variables or an object with a property for each webpage.

Including a Web Page

To embed a webpage, add an ng-inlcude directive. It can be used as an element. In this case, add an attribute named src. Assign the variable you had attached in the controller. If you had attached the variable using the this object, access the variable from an instance of the controller. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Country</title>
<script src="../../Scripts/angular.js"></script>
</head>
<body ng-app="country">
    <div ng-controller="CountryController as cc">
        <ng-include src="cc.province"></ng-include>
    </div>
<script type="text/javascript">
    var app = angular.module('country', []);

    app.controller('CountryController', [function () {
        this.province = 'Government.html';
    }]);
</script>
</body>
</html>

The ng-inlcude directive can also be used as an attribute to an HTML element. In this case, assign the variable of the controller to it. Here is an example:

<div ng-include="cc.privince"></div>

The ng-inlcude directive can also be used as a CSS class. In this case, set the value of the attribute as ng-inlcude and assign the name created in the controller to it.

Embedding Web Pages

The essence of a single-page application is to have different sections in a single webpage so that each section can be updated independently. To take care of this by inclusing, after creating the desired webpages, in an AngularJS controller, you can create a variable for each webpage and attach it appropriately. In the view, use the ng-inlcude directive to access each webpage in the section of your choice. Here is an example:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Country</title>
<script src="Scripts/angular.js"></script>
</head>
<body ng-app="country">
    <div ng-controller="CountryController as cc">
        <div ng-include="cc.state"></div>
        <hr />
        <ng-include src="cc.province"></ng-include>
    </div>
<script type="text/javascript">
    var app = angular.module('country', []);

    app.controller('CountryController', [function () {
        this.state = 'Government.html';
        this.province = 'Index.html';
    }]);
</script>
</body>
</html>

You can also create the values in the controller as an array. In the controller, you can create an object and add a property for each webpage. Here are examples:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Country</title>
<script src="../../Scripts/angular.js"></script>
</head>
<body ng-app="country">
    <div ng-controller="CountryController as cc">
        <div ng-include="cc.link.state"></div>
        <hr />
        <ng-include src="cc.link.province"></ng-include>
        <hr />
        <div class="ng-include:cc.link.parks"></div>
    </div>
<script type="text/javascript">
    var app = angular.module('country', []);

    app.controller('CountryController', [function () {
        this.link = {
            state: 'Government.html',
            province: 'Index.html',
            parks: 'Parks.html'
        };
    }]);
</script>
</body>
</html>

Practical LearningPractical Learning: Ending the Lesson


Previous Copyright © 2017-2019, FunctionX Next