forked from bennadel/JavaScript-Demos
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.htm
193 lines (140 loc) · 5.29 KB
/
index.htm
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
<!doctype html>
<html ng-app="Demo">
<head>
<meta charset="utf-8" />
<title>
Looking At $compile() And MaxPriority In AngularJS
</title>
<link rel="stylesheet" type="text/css" href="./demo.css"></link>
</head>
<body ng-controller="AppController">
<h1>
Looking At $compile() And MaxPriority In AngularJS
</h1>
<!--
The bn-friend directive will dyanmically add other AngularJS directives to
this element and then compile them.
-->
<div bn-friend="friend" bn-log="Outer div.">
My
<span ng-show="friend.isBest" bn-log="Inner span.">best</span>
friend is {{ friend.name }}
</div>
<p>
<em>NOTE: <a href="index2.htm">Run version without isolate-scope</a></em>
</p>
<!-- Load scripts. -->
<script type="text/javascript" src="../../vendor/jquery/jquery-2.1.0.min.js"></script>
<script type="text/javascript" src="../../vendor/angularjs/angular-1.2.16.min.js"></script>
<script type="text/javascript">
// Create an application module for our demo.
var app = angular.module( "Demo", [] );
// -------------------------------------------------- //
// -------------------------------------------------- //
// I control the root of the application.
app.controller(
"AppController",
function( $scope ) {
$scope.friend = {
name: "Kim",
isBest: true
};
console.log( "Demo scope:", $scope );
}
);
// -------------------------------------------------- //
// -------------------------------------------------- //
// I log to the console during the linking function so we can see when things
// are being executed (and how many times they are being executed).
app.directive(
"bnLog",
function() {
// I bind the JavaScript events to the scope.
function link( $scope, element, attributes ) {
var now = ( new Date() ).getTime();
console.log( "Log [", attributes.bnLog, "]", now );
// Logging scope so you can see how scope is affected.
console.log( $scope );
}
// Return the directive configuration.
return({
link: link,
priority: 1010,
restrict: "A"
});
}
);
// -------------------------------------------------- //
// -------------------------------------------------- //
// I dynamically add new directives to the current element.
app.directive(
"bnFriend",
function( $compile ) {
// I augment the template element DOM structure before linking.
function compile( tElement, tAttributes ) {
// Add a static HTML attribute.
tElement.attr( "class", "friend" );
// Add the ng-class directive. Notice that the item reference here
// is the ISOLATE scope reference.
tElement.attr( "ng-class", "{ best: isolateFriend.isBest }" );
// At this point, the ng-class directive WILL NOT be automatically
// compiled. As such, we need to explicitly compile the element,
// starting at the max-priority of the current directive. This will
// compile all directives on this element, lower than 1500, AND all
// the content of the element (regardless of priority).
// --
// NOTE: This is why we need to use TERMINAL in our directive
// configuration - if we didn't then lower-priority directives on the
// element would actually be compiled and linked twice.
var sublink = $compile( tElement, null, 1500 );
// I bind the JavaScript events to the scope.
function link( $scope, element, attributes, _, transclude ) {
// Because we are using the ISOLATE scope, in this case, we have
// to transclude the content. If we don't do this, then the call
// to $compile() above and sublink() below will end up linking
// the element CONTENT to the ISOLATE scope, which will break
// our references. So, instead, what we have to do is allow the
// content to be transcluded and linked to the outer scope
// (outside of our directive).
transclude(
function( content ) {
element.append( content );
}
);
// Link the compiled directives that we dynamically added to the
// current element. This will also link any directives that were
// already on the element, but were at a lower priority.
// --
// NOTE: We probably we want to do this after the transclude()
// since a directive is supposed to be able to rely on the DOM
// of its child content.
sublink( $scope );
}
return( link );
}
// Return the directive configuration.
// --
// NOTE: There a bunch of little interactions going on here. For
// starters, we have to TERMINAL in our configuration otherwise lower-
// priority directives on the same element would compile twice (due to
// our explicit call to $compeil()). Also, since we are using the ISOLATE
// scope (for this demo - not required to use maxPriority), we also have
// to use TRANSCLUDE; if we didn't, then our the elements child content
// would be inappropriately linked to the ISOLATE scope, not to the
// "parent" scope in the scope chain. If we didn't use ISOLATE scope, we
// would NOT have to the use TRANSCLUDE.
return({
compile: compile,
priority: 1500,
restrict: "A",
scope: {
isolateFriend: "=bnFriend"
},
terminal: true,
transclude: true
});
}
);
</script>
</body>
</html>