Archive for September, 2014

Anonymous Functions and Closures – the ‘use’ Keyword

Monday, September 22nd, 2014

Anonymous Functions
PHP 5.3 supports the use of anonymous functions. An unnamed function can be created and assigned to a variable and then the variable can be used like an actual function. Consider the following example:

1
2
3
4
5
6
7
8
<?php
$mult = function($x)
    {
    return $x * 5;
    };
 echo $mult(2);  // 10

?>

Closures
Closures are anonymous functions that have access to variables not defined within themselves. A closure can be created using the ‘use’ keyword. Consider the following example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php

$multiply = function($multiplier)
{
    return function($x) use ($multiplier)  // 'use' gives access to multiplier
    {
        return $x * $multiplier;
    };
};
 
// $mul5 now contains a function that returns a number multiplied by 5
$mult5 = $multiply(5);
 
// $mul7 contains a function that returns a number multiplied by 7
$mult7 = $multiply(7);
 
echo $mult5(5);  // 25
echo $mult7(5);  // 35
 
?>

This is a little different to closures in JavaScript that automatically have access to variables outside their scope.

There are other ways to pass variables to the anonymous functions shown above. The variables could be passed as arguments or the variables could have been declared as global. The latter case can be become quite messy, however. Using the ‘use’ keyword is an elegant alternative to both methods.

The Java paint() Method

Friday, September 19th, 2014

This is a very simple example of Java’s paint() method. The paint() method takes an instance of the Graphics class. The Graphics class contain methods which are used for graphics operations. The following code paint a blue rectangle onto a JPanel component.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.awt.Graphics;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Paint extends JPanel {

   public static void main(String[] a) {
      JFrame f = new JFrame();
      f.setSize(400, 400);
      Paint p = new Paint();
      f.add(p);
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      f.setVisible(true);
   }
   @Override
   public void paint(Graphics g) {
       g.setColor(Color.blue);
       g.fillRect (5, 15, 50, 75);
     
   }
}

Single Page Applications with Backbone.js and AngularJS

Thursday, September 11th, 2014

Hash Tags
The hash tag (#) is used when linking to anchors within a current web page. The use of anchors allows the user to navigate to different parts of the page without going to a new URL. For example,

navigates to the part of the page with anchor

Both Backbone and AngularJS make use of # for routing application URLs in single page applications. In both cases, all links in the application should target “#/action” or “#action”. e.g. http://example.com/#/user. When the user clicks on different links within the application, instead of going to a different place on the page, different portions of the JavaScript in the code get executed.

Backbone.js Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<!DOCTYPE html>
<html>
<head>
<title>Backbone Application</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"></script>
</head>
<body>

<ul>
<li><a href="#">Home</a></li>
<li><a href="#/about">About</a></li>
<li><a href="#/contact">Contact</a></li>
<li><a href="#/redirect">Redirect</a></li>
</ul>

<div class="content"></div>
 
<script type="text/template" id="home-template">
<p><%= value %></p>
</script>

<script type="text/template" id="about-template">
<p><%= value %></p>
</script>

<script type="text/template" id="contact-template">
<p><%= value %></p>
</script>

<script type="text/template" id="redirect-template">
<p>This illustrates the use of backbone's router.navigate('nav', {trigger:true})
which automatically redirects to other locations in the application.  For example,
after saving, updating or deleting data from a database, you might might want to
show some kind of 'success' page.</p>
</script>


<script type="text/javascript">

var Router = Backbone.Router.extend({
   routes: {
    "": "homeview", // url:event that fires
    "about": "aboutview",
    "contact": "contactview",
    "redirect":"redirectview"
  },

// the 'home' view
homeview: function() {
    var content = "welcome to the home page";
    var template = _.template($('#home-template').html(), {value: content});
    $(".content").html(template);
    var HomeView = Backbone.View.extend({
    el: '.content',  
    initialize:function(){
        this.render();
    },
    render: function () {
        this.$el.html(template);
    }
});
var hmview = new HomeView();
},

// the 'about' view
aboutview: function() {
    var content = "welcome to the about page";
    var template = _.template($('#about-template').html(), {value: content});
    $(".content").html(template);
    var AboutView = Backbone.View.extend({
    el: '.content',  
    initialize:function(){
        this.render();
    },
    render: function () {
        this.$el.html(template);
    }
});
var abtview = new AboutView();
},

// the 'contact us' view
contactview: function() {
    var content = "welcome to the contact us page";
    var template = _.template($('#contact-template').html(), {value: content});
    $(".content").html(template);
    var ContactView = Backbone.View.extend({
    el: '.content',    
    initialize:function(){
        this.render();
    },
    render: function () {
        this.$el.html(template);
    }
});
var conview = new ContactView();
},

// demonstrates the automatic redirect functionality
redirectview: function() {
    alert('On closure this we will automatically redirect to another location in the application.');
    router.navigate('redirect', {trigger:true});
    var template = _.template($('#redirect-template').html(), {});
    $(".content").html(template);
    var RedirectView = Backbone.View.extend({
    el: '.content',  
    initialize:function(){
        this.render();
    },
    render: function () {
        this.$el.html(template);
    }
});
var rdview = new RedirectView();
}
});
var router = new Router;

/*
This is an alternative syntax  to the above that uses JQuery's "on" method
 
router.on('route:homeview', function() {
   ...
 }
*/

// Start Backbone history
Backbone.history.start();
</script>

</body>
</html>

See the live demo here

The equivalent of the above using AngularJS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular-route.js"></script>
</head>
<body>

<div ng-app="myApp">

<ul>
<li><a href="#">Home</a></li>
<li><a href="#/about">About</a></li>
<li><a href="#/contact">Contact</a></li>
<li><a href="#/redirect">Redirect</a></li>
</ul>

<div ng-view></div>

</div>

<script>
// create a new module
// also include ngRoute for all our routing needs
   
var myApp = angular.module('myApp', ['ngRoute']);

// configure the routes
   
myApp.config(function($routeProvider) {
/*
AngularJS's $routeProvider has a very basic api for defining application's routes.
$routeProvider.when() is used to match a url pattern to a view while
$routeProvider.otherwise() is used to render a view when there is no
match to a url pattern.
*/


$routeProvider

// route for the home page
  .when('/', {
         templateUrl : 'pages/home.html',
         controller  : 'homeController'
        })

// route for the about page
.when('/about', {
                 templateUrl : 'pages/about.html',
                 controller  : 'aboutController'
              })

// route for the contact page
.when('/contact', {
                   templateUrl : 'pages/contact.html',
                   controller  : 'contactController',
                })

// route for the redirect page
.when('/redirect', {
                    templateUrl : 'pages/redirect.html',
                    controller  : 'redirectController',
                    // automatically redirect
                    redirectTo: '/redirect'
                });
    });
   
// create the controller and inject Angular's $scope
myApp.controller('homeController', function($scope) {
// create a message to display in the view
$scope.message = 'welcome to the home page';
    });

myApp.controller('aboutController', function($scope) {
    $scope.message = 'welcome to the about page.';
    });

myApp.controller('contactController', function($scope) {
    $scope.message = 'welcome to the contact us page.';
    });

myApp.controller('redirectController', function($scope) {
    $scope.message = 'This illustrates the use of AngularJS\'s  redirectTo method which automatically redirects to other locations in the application.  For example, after saving, updating or deleting data from a database, you might might want to show some kind of \'success\' page.';
    alert('On closure this we will automatically redirect to another location in the application.');
    });

</script>

</body>
</html>

Directory Structure

index.html
pages
|_ home.html
|_ about.html
|_ contact.html
|_ redirct.html

home.html/about.html/contact.html/redirect.html

1
2
3
<div>
<p>{{ message }}</p>
</div>

See the live demo here

JavaScript Prototype Property

Tuesday, September 9th, 2014

With the prototype property it is possible to add properties and methods to an object. In a similar manner to other languages such as PHP and Java, prototyping allows objects to inherit, override, and extend functionality. Prototyping is best illustrated with an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!DOCTYPE HTML>
<html lang="en-US">
<head></head>
 
<script>
// add a base object (functions are objects in JavaScript)
var base = function() {}

//Add a multiply function to base using prototype
base.prototype.multiply = function(a,b){
return a*b;}

/* we could also write this using object literal notation
base.prototype = {
multiply: function(a,b){
return a* b;
}
}
*/


//Add a property to base
base.prototype.message = "hello from base";

/* we could do this in object literal notation but we need
to use __proto__.  However, this may not be supported in all
browsers.
base.__proto__ = {
message:  'hello from base'
}
*/


var obj = new base();
alert(obj.multiply(3,5));  // 15

//Access message property added to base
alert(obj.message); // hello from base

Inheritance

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//  Inherit from base by doing the following:

//create a new object with a variable 'constant'
var calc = function(){
this.constant = 10;
}

/*
allow calc to access all of base's properties and methods by
assigning a new base instance to calc's prototype property
*/

calc.prototype = new base();  

var c = new calc();
alert(c.multiply(10,10));  // 100

Overriding

1
2
3
4
5
6
7
8
9
10
11
/*
override the existing multiply function by defining a new multiply
function assigning it calc's prototype property.
*/

calc.prototype.multiply = function(a,b){
return a*b - this.constant;
}

var co = new calc();
alert(co.multiply(10,10)); // 90
alert(co.constant); // 10

The ‘static’ Keyword

Monday, September 8th, 2014

Declaring class properties or methods as static makes them accessible without needing an instantiation of the class. A property declared as static cannot be accessed with an instantiated class object (though a static method can). Also, a static variable within a function will not lose its value when the function exits and will still hold that value should the function be called again. All of this is illustrated in the following example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php

class A {

 // Class property
static $counter = 0;

 // Class method
public static function keep_track() {
   static $count = 0;
   $count++;
   self::$counter++;
   echo "count = " . $count . " : counter =  " . self::$counter . "<br />";
}
}

//Access through instantiation of the class.
$obj = new A();
$obj->keep_track();  
//$obj->counter;  // Error!

//Access without needing an instantiation of the class.
A::keep_track();  
A::keep_track();  
//echo A::$count;  // Error!
echo "class property: " . A::$counter;  

?>

The code outputs:

1
2
3
4
count = 1 : counter = 1
count = 2 : counter = 2
count = 3 : counter = 3
class property: 3

Using Backbone.js with Underscore.js and Handlebars.js

Wednesday, September 3rd, 2014

Underscore.js is the default templating engine for Backbone.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<!DOCTYPE html>
<html>
<head>
<title>Backbone Application</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"></script>
</head>
<body>
 
<div class="content"></div>
 
<script type="text/template" id="person-list-template">
<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Email</th>
    </tr>
  </thead>
  <tbody>
    <% _.each(value, function(person) { %>
      <tr>
        <td><%= person.get('name') %></td>
        <td><%= person.get('email') %></td>
      </tr>
    <% }); %>
  </tbody>
</table>
</script>

<script type="text/javascript">

var Person = Backbone.Model.extend({
    defaults: {
        name: 'Dave Smith',
        email: 'dave@bb.com'
    }
});
 
var doe = new Person({ id: 1, name: 'John Doe', email: 'johndoe@bb.com' });
var hancock = new Person({ id: 2, name: 'John Hancock', email: 'johnhancock@bb.com' });
var jefferson = new Person({ id: 3, name: 'Thomas Jefferson', email: 'thomasjefferson@bb.com'});


var Persons = Backbone.Collection.extend({
    model: Person
});
 
var personArray = [doe, hancock, jefferson];
var persons = new Persons(personArray);  


var template = _.template($('#person-list-template').html(), {value: persons.models});
/*
At this point we could use:
var template = _.template($('#person-list-template').html(), {value: persons.toJSON()});
If we do then the iterator becomes
<% _.each(value, function(person) { %>
      <tr>
        <td><%= person.name %></td>
        <td><%= person.email %></td>
      </tr>
    <% }); %>
*/


$(".content").html(template);

var PersonsListView = Backbone.View.extend({
    el: '.content',
     
    initialize:function(){
        this.render();
    },
    render: function () {
        this.$el.html(template);
    }
});
var personslistview = new PersonsListView();


</script>

</body>
</html>

However, some people prefer other options. Handlebars is very popular and uses the mustache style syntax which involves the use of {{ brackets }} to indicate dynamic values.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<!DOCTYPE html>
<html>
<head>
<title>Backbone Application</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"></script>
<script src ="//cdnjs.cloudflare.com/ajax/libs/handlebars.js/2.0.0-alpha.4/handlebars.js"></script>
</head>
<body>
 
<div class="content"></div>
 
<script id="person-list-template" type="text/x-handlebars-template">
<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Email</th>
    </tr>
  </thead>
  <tbody>
     {{#each []}}
      <tr>
        <td>{{ this.name }}</td>
        <td>{{ this.email }}</td>
      </tr>
     {{/each}}
  </tbody>
</table>
</script>
 
 
<script type="text/javascript">

var Person = Backbone.Model.extend({
    defaults: {
        name: 'Dave Smith',
        email: 'dave@bb.com'
    }
});
 
var doe = new Person({ id: 1, name: 'John Doe', email: 'johndoe@bb.com' });
var hancock = new Person({ id: 2, name: 'John Hancock', email: 'johnhancock@bb.com' });
var jefferson = new Person({ id: 3, name: 'Thomas Jefferson', email: 'thomasjefferson@bb.com'});


var Persons = Backbone.Collection.extend({
    model: Person
});
 
var personArray = [doe, hancock, jefferson];
var persons = new Persons(personArray);  

var PersonsListView = Backbone.View.extend({
    el: '.content',
    initialize:function(){
        this.render();
    },
    render: function () {
        var source = $('#person-list-template').html();
        var template = Handlebars.compile(source);
        var html = template(persons.toJSON());
        this.$el.html(html);
    }
});
var personslistview = new PersonsListView();
</script>
</body>
</html>

Simple AngularJS REST Example

Wednesday, September 3rd, 2014

This is a simple AngularJS example that uses the Bootstrap framework for styling.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
</head>
<body>
<div ng-app="myApp" ng-controller="formController">
<div class = "container">

<h3>PUT Request</h3>

<script type="text/ng-template" id="tableTemplate.html">
<div class="table-responsive">
<table ng-show="formSubmitted" class="table table-striped">
  <thead>
    <tr>
      <th class="col-md-2">id</th>
      <th class="col-md-5">name</th>
      <th class="col-md-5">email</th>
    </tr>
  </thead>
  <tbody>
  <tr ng-repeat="x in names">  <!-- iterate through [{...},{...}, ...] -->
    <td>{{ x.id }}</td>
    <td>{{ x.name }}</td>
    <td>{{ x.email }}</td>
    <tr>
  </tbody>
</table>
</div>
</script>

<form class="form-horizontal" ng-submit = "processForm()" role = "form">
<div class="form-group">
<label class="col-sm-2 control-label">id:</label>
<div class="col-sm-10">
<input type = "text"  name = "id" ng-model = "formData.id">
</div>
</div>

<div class="form-group">
<label class="col-sm-2 control-label">name:</label>
<div class="col-sm-10">
<input type = "text" name = "name" ng-model = "formData.name">
</div>
</div>

<div class="form-group">
<label class="col-sm-2 control-label">email:</label>
<div class="col-sm-10">
<input type = "email" name = "email" ng-model = "formData.email">
</div>
</div>

<button class="btn btn-success" ng-disabled="error || incomplete">
<span class="glyphicon glyphicon-save"></span> Save Changes
</button>
</form>

<div ng-include="'tableTemplate.html'"></div>

</div>
</div>

<script>
var app = angular.module('myApp',[]);
app.controller("formController", function($scope,$http){
    $scope.formData = {};
    $scope.processForm = function()
    {
   
   // PUT /users/id
    var url = 'http://localhost/angular/users/' + $scope.formData.id;
    var data = '{"name": "' + $scope.formData.name  + '", "email":"' + $scope.formData.email + '"}';
    $http({method: 'PUT', url: url, data: data}).success(function(response)    
    {
     $scope.names = response;
     // display the table when the form is submitted
     $scope.formSubmitted = true;
    });

 /*
     // GET /users
    $http({method: 'GET', url: 'http://localhost/angular/users'}).success(function(response)    
    {$scope.names = response;});

    // GET /users/id
    var url = 'http://localhost/users/' + $scope.formData.id;
    $http({method: 'GET', url: url}).success(function(response)    
    {$scope.names = response;});

    // POST /users
    var data = '{"name": "' + $scope.formData.name  + '", "email":"' + $scope.formData.email + '"}';
    $http({method: 'POST', url: 'http://localhost/users', data: data}).success(function(response)    
    {$scope.names = response;});

    // DELETE /users/id
    var url = 'http://localhost/users/' + $scope.formData.id;
    $http({method: 'DELETE', url: url}).success(function(response)    
    {$scope.names = response;});
*/

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

Route all requests to index.php
.htaccess:

1
2
3
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]

index.php:
On the server side we use the Slim PHP micro framework for handling the REST requests.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<?php
header('Content-Type: application/json');
require 'Slim/Slim.php';
\Slim\Slim::registerAutoloader();

$app = new \Slim\Slim();

$app->get('/users', 'getnames');
$app->get('/users/:id', 'getname');
$app->post('/users', 'addname');
$app->put('/users/:id', 'updatename');
$app->delete('/users/:id', 'deletename');

$app->run();

function getnames() {
$out = array();
$out[0]['id'] = 1;
$out[0]['name'] = 'John Doe';
$out[0]['email'] = 'johndoe@angular.com';
$out[1]['id'] = 2;
$out[1]['name'] = 'John Hancock';
$out[1]['email'] = 'johnhancock@angular.com';
echo json_encode($out);
}

function getname($id) {
$out = array();
if ($id == 1 || $id == 'tom'){
$out[0]['id'] = $id;
$out[0]['name'] = 'John Doe';
$out[0]['email'] = 'johndoe@angular.com';
}
if ($id == 2 || $id == 'dick'){
$out[0]['id'] = $id;
$out[0]['name'] = 'John Hancock';
$out[0]['email'] = 'johnhancock@angular.com';
}
echo json_encode($out);
}

function addname() {
$jsonmessage = \Slim\Slim::getInstance()->request();
$message = json_decode($jsonmessage->getBody());  
$out = array();
$out[0]['name'] = $message->name . " has been added";
$out[0]['email'] = $message->email . " has been added";
echo json_encode($out);
}

function updatename($id) {
$jsonmessage = \Slim\Slim::getInstance()->request();
$message = json_decode($jsonmessage->getBody());
$out = array();
$out[0]['id'] = $id;
$out[0]['name'] = "updated to: " . $message->name;
$out[0]['email'] = "updated to: " . $message->email;
echo json_encode($out);
}

function deletename($id) {
$out = array();
$out[0]['id'] = $id;
$out[0]['name'] = $message->name . " has been deleted";
$out[0]['email'] = $message->email . " has been deleted";
echo json_encode($out);
}
?>

Slim returns the following JSON response for a GET request.

1
[{"id":1,"name":"John Doe","email":"johndoe@angular.com"},{"id":2,"name":"John Hancock","email":"johnhancock@angular.com"}]

AngularJS Custom Directives

An alternative to using the built-in directive

1
<div ng-include="'tableTemplate.html'"></div>

is to place the data binding expression into a custom directive as follows:

1
2
3
4
5
6
7
app.directive('myDirective', function() {
    return {
        replace: true,
        restrict: 'AE',  //E = element, A = attribute, C = class, M = comment
        templateUrl: 'tableTemplate.html'
          }
});

and replace the ng-include directive with

1
<div my-directive></div>

AngularJS automatically makes the connection between the my-directive directive and the directive name myDirective by removing the dash and converting the result to camelCase syntax.

There are many other properties that can be used in directives. Some of the key ones are shown below:

1
2
3
4
5
6
7
8
9
10
11
12
13
template: '<div>{{ myVal }}</div>',  // Use this template
controller: controllerFunction, //Embed a custom controller
link: function ($scope, element, attrs) { // DOM manipulation
      element.bind('click', function () {
          element.html('You clicked me!');
           });
      element.bind('mouseenter', function () {
          element.css('background-color', 'yellow')
           });
      element.bind('mouseleave', function () {
          element.css('background-color', 'white');
           });
      }