You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
323 lines
7.1 KiB
323 lines
7.1 KiB
# AngularJS - Custom Directives
|
|
|
|
## Lesson Objectives
|
|
|
|
1. Explain what a custom directive is
|
|
1. Create your own custom directive
|
|
1. Include a template already in the HTML
|
|
1. Reference a controller by name
|
|
1. Get values from other attributes placed on the directive tag
|
|
|
|
## Explain what a custom directive is
|
|
|
|
You can create your own directives, just like ng-click, ng-submit, etc. This allows you to abstract away complicated/reusable code into an attribute, a class, a comment, or even your own HTML element!
|
|
|
|
## Set Up
|
|
- `mkdir custom_directives`
|
|
- `cd custom_directives`
|
|
- `touch app.js index.html product.html`
|
|
- `atom .`
|
|
|
|
```html
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.2/angular.min.js'></script>
|
|
<script type="text/javascript" src="app.js"></script>
|
|
</head>
|
|
<body ng-app="MyApp">
|
|
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
```js
|
|
const app = angular.module('MyApp', []);
|
|
```
|
|
|
|
## Create your own custom directive
|
|
|
|
Here's our custom HTML element:
|
|
|
|
```html
|
|
<product-title></product-title>
|
|
```
|
|
|
|
the full html:
|
|
|
|
file: index.html
|
|
```html
|
|
<!DOCTYPE html>
|
|
<html >
|
|
<head>
|
|
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.2/angular.min.js'></script>
|
|
<script type="text/javascript" src="js/app.js"></script>
|
|
</head>
|
|
<body ng-app="MyApp">
|
|
<product-title></product-title>
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
Here's how we define its behavior:
|
|
|
|
file: js/app.js
|
|
```javascript
|
|
|
|
const app = angular.module('MyApp', []);
|
|
|
|
app.directive('product', function(){
|
|
return {
|
|
restrict: 'E', // E=element, A=attribute, C=class, M=comment, can be combined
|
|
templateUrl: 'product.html', //template to replace directive element
|
|
controller(){ //controller constructor function
|
|
this.name = "arduino"
|
|
},
|
|
controllerAs: 'ctrl' //how it should be instantiated (Controller as ctrl)
|
|
};
|
|
});
|
|
```
|
|
|
|
**NOTE** when using multiple custom directives, or even multiple controllers, make sure they are instantiated with different aliases (e.g. ctrl1, ctrl2, etc. as opposed to ctrl, ctrl, ctrl, etc.)
|
|
|
|
Here's the external template referenced above:
|
|
|
|
file: partials/product-title.html
|
|
```html
|
|
<h3>
|
|
<p>product template</p>
|
|
This is the product name:
|
|
{{ctrl.name}}
|
|
</h3>
|
|
```
|
|
|
|
## Include a template already in the HTML
|
|
|
|
Just like with includes, we can specify templates that are ids in our HTML. Let's make a new on for product-title
|
|
|
|
## And Reference a controller by name
|
|
You can reference a controller by name, instead of creating the controller within the directive itself
|
|
|
|
file: index.html
|
|
```html
|
|
<!DOCTYPE html>
|
|
<html >
|
|
<head>
|
|
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.2/angular.min.js'></script>
|
|
<script type="text/javascript" src="js/app.js"></script>
|
|
</head>
|
|
<body ng-app="MyApp">
|
|
<product></product>
|
|
<product-title></product-title>
|
|
<script type="text/ng-template" id='product-title.html'>
|
|
<h2>{{ctrl.name}}</h2>
|
|
</script>
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
file js/app.js
|
|
```javascript
|
|
app.directive('productTitle', function(){
|
|
return {
|
|
restrict: 'E', // E=element, A=attribute, C=class, M=comment, can be combined
|
|
templateUrl: 'product-title.html', //template to replace directive element
|
|
controller: 'MainController',
|
|
controllerAs: 'ctrl', //how it should be instantiated
|
|
};
|
|
});
|
|
|
|
app.controller('MainController', function(){
|
|
this.name = 'main name'
|
|
});
|
|
```
|
|
|
|
|
|
## Get values from other attributes placed on the directive tag
|
|
|
|
You can add other attributes onto your directive tag...
|
|
|
|
```html
|
|
<product-title awesome="super neat"></product-title>
|
|
```
|
|
|
|
and place them on your scope:
|
|
|
|
file: js/app.js
|
|
```javascript
|
|
app.directive('productTitle', function(){
|
|
return {
|
|
restrict: 'E', // E=element, A=attribute, C=class, M=comment, can be combined
|
|
templateUrl: 'product-title.html', //template to replace directive element
|
|
controller: 'MainController',
|
|
controllerAs: 'ctrl', //how it should be instantiated
|
|
scope: {
|
|
myAttribute: '@awesome'
|
|
}
|
|
};
|
|
});
|
|
|
|
app.controller('MainController', function(){
|
|
this.name = 'main name'
|
|
});
|
|
```
|
|
|
|
Now you can reference the `myAttribute` property of scope in your html
|
|
|
|
file: index.html
|
|
```html
|
|
<body ng-app="MyApp">
|
|
<product></product>
|
|
<product-title awesome="super neat"></product-title>
|
|
<script type="text/ng-template" id='product-title.html'>
|
|
<h2>{{ctrl.name}}</h2>
|
|
{{myAttribute}}
|
|
</script>
|
|
</body>
|
|
```
|
|
|
|
**You can change the `@` to `=` and it will attempt to evaluate the attribute's value as javascript**
|
|
|
|
file: js/app.js
|
|
```javascript
|
|
const app = angular.module('MyApp', []);
|
|
|
|
app.directive('product', function(){
|
|
return {
|
|
templateUrl:'partial2.html',
|
|
controller: 'MainController',
|
|
controllerAs: 'main',
|
|
scope: {
|
|
myAttribute: '=awesome'
|
|
}
|
|
}
|
|
});
|
|
|
|
app.controller('MainController', function(){
|
|
this.name = 'main name'
|
|
});
|
|
```
|
|
|
|
file: index.html
|
|
```html
|
|
<body ng-app="MyApp">
|
|
<product></product>
|
|
<product-title awesome="super neat"></product-title>
|
|
<script type="text/ng-template" id='product-title.html'>
|
|
<h2>{{ctrl.name}}</h2>
|
|
{{myAttribute}}
|
|
</script>
|
|
</body>
|
|
```
|
|
|
|
Lastly, you can also set the directive itself to be an attribute with a value
|
|
|
|
file: index.html
|
|
```html
|
|
<div squirrel="flying squirrel"></div>
|
|
<script type="text/ng-template" id='partial3.html'>
|
|
Template 3!!
|
|
{{myAttribute}}
|
|
</script>
|
|
```
|
|
|
|
file: js/app.js
|
|
```javascript
|
|
app.directive('squirrel', function(){
|
|
return {
|
|
templateUrl:'partial3.html',
|
|
controller: 'MainController',
|
|
controllerAs: 'main',
|
|
scope: {
|
|
myAttribute: '@squirrel'
|
|
}
|
|
}
|
|
});
|
|
|
|
app.controller('MainController', function(){
|
|
});
|
|
```
|
|
|
|
|
|
#### All the code
|
|
|
|
index.html
|
|
|
|
```html
|
|
<!DOCTYPE html>
|
|
<html >
|
|
<head>
|
|
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.2/angular.min.js'></script>
|
|
<script type="text/javascript" src="app.js"></script>
|
|
</head>
|
|
<body ng-app="MyApp">
|
|
<product></product>
|
|
<product-title awesome="super neat"></product-title>
|
|
<script type="text/ng-template" id='product-title.html'>
|
|
<h2>{{ctrl.name}}</h2>
|
|
{{myAttribute}}
|
|
</script>
|
|
|
|
<div squirrel="flying squirrel"></div>
|
|
<script type="text/ng-template" id='partial3.html'>
|
|
Template 3!!
|
|
{{myAttribute}}
|
|
</script>
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
product.html
|
|
|
|
```html
|
|
<h3>
|
|
<p>product template</p>
|
|
This is the product name:
|
|
{{ctrl.name}}
|
|
</h3>
|
|
```
|
|
|
|
app.js
|
|
```js
|
|
const app = angular.module('MyApp', []);
|
|
|
|
app.directive('product', function(){
|
|
return {
|
|
restrict: 'E', // E=element, A=attribute, C=class, M=comment, can be combined
|
|
templateUrl: 'product.html', //template to replace directive element
|
|
controller(){ //controller constructor function
|
|
this.name = "arduino"
|
|
},
|
|
controllerAs: 'ctrl' //how it should be instantiated (Controller as ctrl)
|
|
};
|
|
});
|
|
|
|
app.directive('productTitle', function(){
|
|
return {
|
|
restrict: 'E', // E=element, A=attribute, C=class, M=comment, can be combined
|
|
templateUrl: 'product-title.html', //template to replace directive element
|
|
controller: 'MainController',
|
|
controllerAs: 'ctrl', //how it should be instantiated
|
|
scope: {
|
|
myAttribute: '@awesome'
|
|
}
|
|
};
|
|
});
|
|
|
|
app.directive('squirrel', function(){
|
|
return {
|
|
templateUrl:'partial3.html',
|
|
controller: 'MainController',
|
|
controllerAs: 'main',
|
|
scope: {
|
|
myAttribute: '@squirrel'
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
app.controller('MainController', function(){
|
|
this.name = 'main name'
|
|
});
|
|
```
|