Angularjs 5 Examples of detailed directive (Directive) Mechanism
The poor autumn http://damoqiongqiu.iteye.com/blog/1917971 in the desert
1. A little note
the role of instruction: implementing semantic tagging
The HTML tags we use are like this:
<div>
<span> A little content </span>
</div>
and using Angularjs's directive (instruction) mechanism, we can implement something like this:
<tabpanel>
<panel> subpanel 1</panel>
<panel> sub-panel 2</panel>
</tabpanel>
Many people may see that this is similar to the taglib in the framework of JSP or struts and so on.
Well, to be honest, that's actually the case, but this is done using JavaScript. Because of this, so many functions that taglib can't do, you can do with it, such as accessing objects in N-level scope (see the 5th example later).
2. Example 1: From the simplest start
"Note: directive's name--1. are characters and cannot be underlined; 2. If you use the Hump naming method, use-to separate the hump word when you use it, such as Trhello, and use Tr-hello in HTML.
<html ng-app='app'>
<body>
<hello></hello>
</body>
<script src="../angular-1.0.3/angular.min.js"></script>
<script src="HelloDirect.js"></script>
</html>
For the < Hello > tag in the above code, the browser obviously doesn't recognize it. The only thing it can do is ignore the tag. So, in order for the browser to recognize this tag, we need to use angular to define a hello instruction (essentially, we need to replace the < Hello > thing with the standard HTML tags that the browser can recognize).
Take a look at this warm JS code:
var appModule = angular.module('app', []);
appModule.directive('hello', function() {
Return {
restrict: 'E',
template: '<div>Hi there</div>',
replace: true
}
};
The above code can be seen at a glance, don't care too much about the details.
Then we can see the following content in the browser:
Angularjs explains the directive mechanism
The actual generated label structure is as follows:
Angularjs explains the directive mechanism
As you can see, the < Hello > has been replaced by the < div > Hi there < / div > tag. This is also the function of the replacement: true configuration in the above JS code. The template configuration item in the code is of course the div tag we want. For the meaning of the restriction: 'e' configuration item, see the following table:
OK, after reading the above table, I believe you have understood the attribute of restrict in seconds, so let's play with some tricks. If the HTML tag we need to replace is very long, obviously it can't be written by splicing strings. At this time, we can use templateurl instead of template, so that we can write the template to a separate HTML file.
3. Example 2: Transform
Let's look at the example, JS code:
var appModule = angular.module('app', []);
appModule.directive('hello', function() {
Return {
restrict: 'E',
template: '<div>Hi there <span ng-transclude></span></div>',
transclude: true
}
};
HTML code:
<html ng-app='app'>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
</head>
<body>
<hello>
<br/>
<span>Original content, < span > < br / >
<span>It's still here. </span>
</hello>
<hello>
</hello>
</body>
<script src="../angular-1.0.3/angular.min.js"></script>
<script src="Transclude.js"></script>
</html>
The operation effect is as follows:
Angularjs explains the directive mechanism
The generated HTML tag structure is as follows:
Angularjs explains the directive mechanism
Compared with the first example, the JS code and HTML code in this example are slightly different. There is an extra include: true in the JS code, and there are child tags in the < Hello > HTML code.
According to our first example, the purpose of the instruction is to replace our customized semantic tags with HTML tags that the browser can recognize. Well, if there are sub tags in our custom tags, what should we do. It's clear that the purpose of the trade is to deal with this situation.
For the current example, the function of include can be simplified into: replace the < Hello > tag with the HTML template we wrote, but the content inside the < Hello > tag remains unchanged.
Obviously, since we didn't add the replace: true option, the < Hello > tag is still there and hasn't been replaced. At the same time, through this example, you will also find a hidden attribute, that is, the browser is actually very intelligent, although it does not know the < Hello > tag, but the page does not make any mistakes, it just silently ignores the tag. how. Is it a blockhouse.
You can add replace: true in the above JS code, and then look at the generated HTML structure.
4. Example 3: About compile and link
JS Code:
var appModule = angular.module('app', []);
appModule.directive('hello', function() {
Return {
restrict: 'E',
template: '<span>Hi there</span>',
replace: true
}
};
appModule.controller('MyController',function($scope) {
$scope.things = [1,2,3,4,5,6];
};
HTML code:
<html ng-app='app'>
<body ng-controller='MyController'>
<div ng-repeat='thing in things'>
{{thing}}.<hello></hello>
</div>
</body>
<script src="../angular-1.0.3/angular.min.js"></script>
<script src="CompileAndLink.js"></script>
</html>
Well, this example is used to explain a little theory, so you can't see a bird just by looking at the effect.
As mentioned before, the essence of instruction is actually a replacement process. Well, in that case, how does angular replace. Well, this process is divided into two stages, that is, the title of this section refers to compile and link.
In short, the compile phase performs label parsing and transformation, and the link phase performs data binding and other operations. For more details, please refer to the analysis in angularjs. I won't go into details here (ER, actually it's because it's a long and troublesome explanation, uncle doesn't want to talk about it here).
So, what's the use of knowing this.
For example, if you have some events that need to be bound to an element, then you need to provide a link function. Please see the next example.
5. Example 4: a more complex example expander
This is an example provided in angularjs, but there is no complete executable code in the book, so here it is for your reference.
JS Code:
var expanderModule=angular.module('expanderModule', [])
expanderModule.directive('expander', function() {
Return {
restrict : 'EA',
replace : true,
transclude : true,
Scope: {
title : '=expanderTitle'
}
template : '<div>'
+ '<div class="title" ng-click="toggle()">{{title}}</div>'
+ '<div class="body" ng-show="showMe" ng-transclude></div>'
+'</div>',
link : function(scope, element, attrs) {
scope.showMe = false;
scope.toggle = function toggle() {
scope.showMe = !scope.showMe;
}
}
}
};
expanderModule.controller('SomeController',function($scope) {
$scope. Title = 'click to expand';
$scope. Text = 'this is the internal content. ';
};
HTML code:
<html ng-app='expanderModule'>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src="../angular-1.0.3/angular.min.js"></script>
<link rel="stylesheet" type="text/css" href="ExpanderSimple.css"/>
</head>
<body>
<div ng-controller='SomeController'>
<expander class='expander' expander-title='title'>
{{text}}
</expander>
</div>
</body>
<script src="ExpanderSimple.js"></script>
</html>
CSS Code:
.expander {
border: 1px solid black;
width: 250px;
}
.expander>.title {
background-color: black;
color: white;
padding: .1em .3em;
cursor: pointer;
}
.expander>.body {
padding: .1em .3em;
}
The operation effect is as follows:
Angularjs explains the directive mechanism
Notice this paragraph in JS code:
link : function(scope, element, attrs) {
scope.showMe = false;
scope.toggle = function toggle() {
scope.showMe = !scope.showMe;
}
}
Let's run examples by ourselves and study them without much explanation.
6. Example 5: a comprehensive example
JS Code:
var expModule=angular.module('expanderModule',[])
expModule.directive('accordion', function() {
Return {
restrict : 'EA',
replace : true,
transclude : true,
template : '<div ng-transclude></div>',
controller : function() {
var expanders = [];
this.gotOpened = function(selectedExpander) {
angular.forEach(expanders, function(expander) {
if (selectedExpander != expander) {
expander.showMe = false;
}
};
}
this.addExpander = function(expander) {
expanders.push(expander);
}
}
}
};
expModule.directive('expander', function() {
Return {
restrict : 'EA',
replace : true,
transclude : true,
require : '^?accordion',
Scope: {
title : '=expanderTitle'
}
template : '<div>'
+ '<div class="title" ng-click="toggle()">{{title}}</div>'
+ '<div class="body" ng-show="showMe" ng-transclude></div>'
+'</div>',
link : function(scope, el