The article presents a tutorial on how to create custom directives, using a sample quiz app and code examples. The quiz app demonstration could be found on following pages. Please excuse me for typos, if found.
Following will be discussed in this article:
- Introduction to quiz app and related custom directives
- Key directives concepts demonstrated with quiz app
- How to use these directives?
Introduction to Quiz App & Related Custom Directives
The objective behind the quiz app is to enable the quiz creators create quick quiz apps by focusing on questions and answers rather than dealing with nitty gritty of web development for creating each app. I was able to create the two sets of questions in flat 10 minutes.
To achieve the above objective, following directives were created:
- iquestion: This directive helps define the questions in the simplest form.
- iscorecard: This directive display scores for the quiz.
This is how questions & answers will be written using custom directive, iquestion. In the following directive, there is an attribute called as “text”. This attribute is used to gather the question and answer options along with right answer. In the text below, the question and answer options is separated by “::” and answer options are separated by “;”. The right answer is prefixed by “__”.
<iquestion text=”Who is sometimes called as Father of AngularJS?::Brad;Igor Minor;__Misko Hevery;Brian Ford”></iquestion>
<iquestion text=”Only one angular app can be automatically bootstrap in an HTML page. Others need to be manually bootstrap?::__True;False”></iquestion>
Following directive can be used to display the score card:
Key directives concept demonstrated with quiz app
Following are key concepts related with directives that got demonstrated in creating the custom directives, iquestion and iscorecard.
- Templating: The custom directives make use of following two templates. The key point to note is that the templating makes the whole thing reusable as an update to the template would update all of the pages using that template. With this, one may not require to touch/update the existing HTML pages having the questions information. The templates are saved in separate files and are accessed in the custom directives using “templateUrl” property.
- Restrict: With restrict property, the directives have been restricted to be used as element only. Note that ‘E’ is being used in the directives code. Other possible ways in which directives can be used are attributes (A), comment (M) and class (C). The reason why the directives, iquestion and iscorecard, have been restricted to “Element” is that these are the key directives of this app and are not intended to decorate existing elements. It also makes it extensible based on the fact that new attribute could be defined to associate additional functionality.
- Isolating Scope: The directives have got their own scope which, in turn, defines custom properties that could be used to retrieve the data from HTML page. It also makes the directives reusable. Take a look at the code to find more about the isolate scope.
- Accessing the parent scope: One could access the parent scope properties and methods from within directive using code such as $scope.$parent.<propertyname> or $scope.$parent.<methodname>
- Parent controller scope as a bridge for directives inter-communication: The parent controller scope acts as a bridge for communication between two directives, iquestion and iscorecard. As a result of score changing due to options chosen by the user, the scorecard changes and the watch from “iscorecard” directive updates it template appropriately.
- Controller within Directive definition: Controllers within directive are used to capture user interactions with the directive.
- Manipulate DOM: As the “Show Answers” is clicked in scorecard, the directive controller updates the parent scope property, displayAnswers. The “iquestion” updates the style on the right answer appropriately due to the fact that it is watching the parent scope property, “displayAnswers”.
How to use these Quiz Directives
I shall be putting these directives code in github. However, if would like to try these directives or extend these directives for your usage, do the following:
- Directive code: http://hello-angularjs.appspot.com/assets/js/quizapp.js
- Template code for iquestion from following link (using view-source): http://hello-angularjs.appspot.com/assets/templates/question.html
- Template code for iscorecard from following link (using view-source): http://hello-angularjs.appspot.com/assets/templates/scorecard.html
Following is the sample HTML page using the above directives:
<!DOCTYPE html> <html ng-app="quizApp"> <head> <title>AngularJS Job Interview Questions - Set 2</title> <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"> </head> <body ng-controller="QuizCtrl"> <div class="container"> <div class="page-header"> <h1>AngularJS Interview Questions - Set 2</h1> </div> <table class="col-md-12"> <tr> <td class="col-md-9" style="vertical-align: top"> <table class="table"> <tr> <td><iquestion text="What are various possible prefixes such as 'ng-' using which Angular directives (for example, ng-app) can be defined?::'ng-', 'data-ng-', 'ng:';'ng-';__'ng-', 'data-ng-', 'ng:', 'x-ng-';'ng-', 'data-ng-','x-ng-'"></iquestion></td> </tr> <tr> <td><iquestion text="What are various possible ways in which angular application can be initialized?::On an element, one could either put simply the attribute such as (ng-app, data-ng-app, ng:app, x-ng-app);Put the named attribute such as (ng-app='demoApp');__Both of the above"></iquestion></td> </tr> </table> </td> <td style="vertical-align: top"><iscorecard></iscorecard></td> </tr> </table> </div> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js"></script> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular-sanitize.min.js"></script> <script src="assets/js/ui-bootstrap-tpls-0.9.0.min.js"></script> <script src="assets/js/quizapp.js"></script> </body> </html>
Please feel free to suggest or comment as I have been doing AngularJS from quite sometime but do not consider myself as an expert or something link that. The idea behind this article is to demonstrate the power of AngularJS directives. I am sure it could be extended or made in a better manner.