To manipulate the DOM in the instruction, we need the link parameter, which requires declaring a function called a link function.
Writing:
Link:function (scope, element, Attrs) {
Manipulate the DOM here
}
If the directive uses the Require option, then the link function will have a fourth parameter that represents the controller or the controller on which the command is dependent.
Require ' Somecontroller ',
Link:function (scope, element, Attrs, Somecontroller) {
Here, you can access the required specified controller by manipulating the DOM.
}
The reason that the link function can manipulate the DOM in the instruction is because of the parameters passed in:scope, element, Attrs
Scope: The current scope associated with the directive element, which can be used to register listeners: scope. $watch ()
element: which is the current directive, which allows you to manipulate the element and its child elements. For example <span My-directive></span> this span is the element used by the instruction My-directive.
attrs: An object that consists of the attributes of the current element.
Here is an example of an example from an official document.
We want to implement a clock that displays the current time according to the given time format, and updates the time every second.
First initialize a time format in the controller:
Controller (' controller ', [' $scope ', function ($scope) {
$scope. Format = ' m/d/yy h:mm:ss a ';
}])
For the time format, obviously we want to introduce the $filter service.
For some operations "every second", it is obvious to introduce the $interval service.
To test the program, we also introduced the $log service to see the output in the browser.
So the custom instructions need to be written like this:
directive (' Myclock ', [' $interval ', ' $filter ', ' $log ', function ($interval, $filter, $log)
This myclock instruction will be injected into $interval, $filter, $log services.
The refresh time display, which requires us to manipulate the DOM in the instruction, outputs the time:
function UpdateTime () {
Element.text ($filter (' Date ') (new Date (), Interformat));
}
Use of $filter methods:
$filter (' Date ') (date, format, timezone)
Reference Https://code.angularjs.org/1.3.16/docs/api/ng/filter/date
Refresh the display every second:
$interval (
function () {
UpdateTime ();
},
1000
);
The complete code is as follows:
<! DOCTYPE html>Scope. MyFormat)); } updatetime (); $interval (function () {updatetime (); }, 1000); } }; }]); </script>Operating effect:
However, we soon found a problem, that is, after modifying the time format, can not immediately refresh the time display, change every second to every five seconds, the problem is more obvious.
Although modifying format causes MyFormat to change because of two-way binding, the latter does not trigger the execution of the UpdateTime () function.
So you need to join $watch Monitor:
<! DOCTYPE html>scope. $watch (' MyFormat ', function (newvalue) {$log. info (' value changed to ' +newvalue); UpdateTime (); });$interval (function () {updatetime (); }, 1000); } }; }]); </script>Note that the first parameter of $watch () is ' myformat ', do not reduce the single quotation marks, and do not write ' Scope.myformat ', ' $scope. MyFormat ', otherwise the newvalue value is undefined.
There is the deletion of the outside of the UpdateTime () call, because in the $watch MyFormat the first time binding, has triggered the listener callback function, so UpdateTime () is also executed immediately.
The code above listens to MyFormat defined at the isolation scope of the instruction, while the official document listens to the My-format attribute of the span element in the DOM, the effect is similar, the code is as follows:
<! DOCTYPE html>Attrs.myformat, function (value) {Interformat = value; UpdateTime (); });Element.on (' $destroy ', function () {$interval. Cancel (Timeoutid); });Timeoutid = $interval (function () {updatetime (); }, 1000); } }; }]); </script>Official documentation points to a problem: $interval registered anonymous functions are not automatically freed when an element is removed, there is a risk of memory leaks, so the code is added:
Element.on (' $destroy ', function () {
$interval. Cancel (Timeoutid);
});
These three lines of code also demonstrate how to add an event listener to an element within a directive, and the official documentation provides another example of the following code:
<! DOCTYPE html>Element.on(' MouseDown ', function (event) {//Prevent default dragging of selected content Event.preventdefault (); StartX = Event.pagex-x; Starty = event.pagey-y;$document. on(' MouseMove ', MouseMove);$document. on(' MouseUp ', MouseUp); }); function MouseMove (event) {y = Event.pagey-starty; x = Event.pagex-startx; Element.css ({top:y + ' px ', left:x + ' px ') }); } function MouseUp () {$document. Off (' MouseMove ', MouseMove); $document. Off (' MouseUp ', MouseUp); } } }; }]); </script>Now review the isolation scope issues mentioned in the previous article to see the following code:
<! DOCTYPE html> scope.greeting = ' AngularJs ' ; } }; }); </script>
Output:
1,Hello angularjs!
2,Hello angularjs!
Although the greeting is initialized to ' world ', but is modified to ' AngularJs ' in the link function, it can be seen that the scope passed to the link function at this time is the upper-level scope (here is Rootscope)
This creates pollution, and in general we do not want the instructions to silently modify the outside variables, the solution is to remove the comments in the Code//scope:{}, the scope of the quarantine instruction.
The output will then become:
1,Hello world!
2,Hello angularjs!
Then look at the following code:
<! DOCTYPE html>Ng-transclude></span> ', scope:{}, Transclude:true, link : function (scope,element,attrs) {scope.greeting = ' AngularJs '; } }; }); </script>{{Greeting}}!</my-directive>Output:
1,Hello world!
2,hello world!
Even though the Ng-transclude directive is placed in the template for the directive definition, but the {{greeting}} binding is placed outside, and the directive has been quarantined, {{greeting}} uses the outside ' world '.
If you comment out scope:{}, the scope of the instruction is not isolated, and the output becomes:
1,Hello angularjs!
2,hello angularjs!
Angularjs Customization Instructions (5)-Link