Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 481176d

Browse files
committed
fixup: better examples
1 parent c3ffb2f commit 481176d

File tree

1 file changed

+30
-19
lines changed

1 file changed

+30
-19
lines changed

src/ng/compile.js

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -952,39 +952,49 @@
952952
* not an intended use case and can lead to misbehaving directives, performance issues, and memory
953953
* leaks.
954954
* A common scenario where this happens is a directive that calls `$compile` in a directive link
955-
* function on the directive element:
955+
* function on the directive element. In the following example, a directive adds a mouseover behavior
956+
* to a button with `ngClick` on it:
956957
*
957958
* ```
958-
angular.module('app').directive('addInput', function($compile) {
959+
angular.module('app').directive('addMouseover', function($compile) {
959960
return {
960961
link: function(scope, element, attrs) {
961-
var newEl = angular.element('<input ng-model="$ctrl.value">');
962-
attrs.$set('addInput', null) // To stop infinite compile loop
962+
var newEl = angular.element('<span ng-show="showHint"> My Hint</span>');
963+
element.on('mouseenter mouseout', function() {
964+
scope.$apply('showHint = !showHint');
965+
});
966+
967+
attrs.$set('addMouseover', null); // To stop infinite compile loop
963968
element.append(newEl);
964969
$compile(element)(scope); // Double compilation
965970
}
966971
}
967972
})
968973
```
969-
* At first glance, it looks like removing the original `addInput` attribute is all there is needed
974+
* At first glance, it looks like removing the original `addMouseover` attribute is all there is needed
970975
* to make this example work.
971976
* However, if the directive element or its children have other directives attached, they will be compiled and
972977
* linked again, because the compiler doesn't keep track of which directives have been assigned to which
973978
* elements.
974979
*
975-
* This can cause unpredictable behavior, e.g. `ngModel` $formatters and $parsers will be
976-
* attached again to the ngModelController. It can also degrade performance, as
977-
* watchers for text interpolation are added twice to the scope.
980+
* This can cause unpredictable behavior, e.g. `ngClick` or other event handlers will be attached
981+
* again. It can also degrade performance, as watchers for text interpolation are added twice to the scope.
982+
*
983+
* Double compilation should therefore be avoided. In the above example, only the new element should
984+
* be compiled:
978985
*
979-
* Double compilation should therefore avoided. In the above example, the better way is to only
980-
* compile the new element:
981986
* ```
982-
angular.module('app').directive('addInput', function($compile) {
987+
angular.module('app').directive('addMouseover', function($compile) {
983988
return {
984989
link: function(scope, element, attrs) {
985-
var newEl = angular.element('<input ng-model="$ctrl.value">');
986-
$compile(newEl)(scope); // Only compile the new element
990+
var newEl = angular.element('<span ng-show="showHint"> My Hint</span>');
991+
element.on('mouseenter mouseout', function() {
992+
scope.$apply('showHint = !showHint');
993+
});
994+
995+
attrs.$set('addMouseover', null);
987996
element.append(newEl);
997+
$compile(newEl)(scope); // Only compile the new element
988998
}
989999
}
9901000
})
@@ -1000,7 +1010,7 @@
10001010
angular.module('app').directive('addOptions', function($compile) {
10011011
return {
10021012
link: function(scope, element, attrs) {
1003-
attrs.$set('addInput', null) // To stop infinite compile loop
1013+
attrs.$set('addOptions', null) // To stop infinite compile loop
10041014
attrs.$set('ngModelOptions', '{debounce: 1000}');
10051015
$compile(element)(scope); // Double compilation
10061016
}
@@ -1010,15 +1020,15 @@
10101020
*
10111021
* In that case, it is necessary to intercept the *initial* compilation of the element:
10121022
*
1013-
* 1. give your directive the `terminal` property and a higher priority than directives
1023+
* 1. Give your directive the `terminal` property and a higher priority than directives
10141024
* that should not be compiled twice. In the example, the compiler will only compile directives
10151025
* which have a priority of 100 or higher.
1016-
* 2. inside this directive's compile function, remove the original directive attribute from the element,
1026+
* 2. Inside this directive's compile function, remove the original directive attribute from the element,
10171027
* and add any other directive attributes. Removing the attribute is necessary, because otherwise the
10181028
* compilation would result in an infinite loop.
1019-
* 3. compile the element but restrict the maximum priority, so that any already compiled directives
1029+
* 3. Compile the element but restrict the maximum priority, so that any already compiled directives
10201030
* are not compiled twice.
1021-
* 4. in the link function, link the compiled element with the element's scope
1031+
* 4. In the link function, link the compiled element with the element's scope
10221032
*
10231033
* ```
10241034
angular.module('app').directive('addOptions', function($compile) {
@@ -1027,9 +1037,10 @@
10271037
terminal: true,
10281038
template: '<input ng-model="$ctrl.value">',
10291039
compile: function(templateElement, templateAttributes) {
1030-
templateAttributes.$set('addOptions', null);
10311040
templateAttributes.$set('ngModelOptions', '{debounce: 1000}');
10321041
1042+
// The third argument is the max priority. Only directives with priority < 100 will be compiled,
1043+
// therefore we don't need to remove the attribute
10331044
var compiled = $compile(templateElement, null, 100);
10341045
10351046
return function linkFn(scope) {

0 commit comments

Comments
 (0)