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

Commit 2ca4170

Browse files
docs($compile): reorganize the life-cycle hooks docs
Closes #14811
1 parent fd57df1 commit 2ca4170

File tree

1 file changed

+122
-106
lines changed

1 file changed

+122
-106
lines changed

src/ng/compile.js

+122-106
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,9 @@
5252
* There are many different options for a directive.
5353
*
5454
* The difference resides in the return value of the factory function.
55-
* You can either return a "Directive Definition Object" (see below) that defines the directive properties,
56-
* or just the `postLink` function (all other properties will have the default values).
55+
* You can either return a {@link $compile#directive-definition-object Directive Definition Object (see below)}
56+
* that defines the directive properties, or just the `postLink` function (all other properties will have
57+
* the default values).
5758
*
5859
* <div class="alert alert-success">
5960
* **Best Practice:** It's recommended to use the "directive definition object" form.
@@ -117,6 +118,125 @@
117118
* });
118119
* ```
119120
*
121+
* ### Life-cycle hooks
122+
* Directive controllers can provide the following methods that are called by Angular at points in the life-cycle of the
123+
* directive:
124+
* * `$onInit()` - Called on each controller after all the controllers on an element have been constructed and
125+
* had their bindings initialized (and before the pre &amp; post linking functions for the directives on
126+
* this element). This is a good place to put initialization code for your controller.
127+
* * `$onChanges(changesObj)` - Called whenever one-way (`<`) or interpolation (`@`) bindings are updated. The
128+
* `changesObj` is a hash whose keys are the names of the bound properties that have changed, and the values are an
129+
* object of the form `{ currentValue, previousValue, isFirstChange() }`. Use this hook to trigger updates within a
130+
* component such as cloning the bound value to prevent accidental mutation of the outer value.
131+
* * `$doCheck()` - Called on each turn of the digest cycle. Provides an opportunity to detect and act on
132+
* changes. Any actions that you wish to take in response to the changes that you detect must be
133+
* invoked from this hook; implementing this has no effect on when `$onChanges` is called. For example, this hook
134+
* could be useful if you wish to perform a deep equality check, or to check a Date object, changes to which would not
135+
* be detected by Angular's change detector and thus not trigger `$onChanges`. This hook is invoked with no arguments;
136+
* if detecting changes, you must store the previous value(s) for comparison to the current values.
137+
* * `$onDestroy()` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
138+
* external resources, watches and event handlers. Note that components have their `$onDestroy()` hooks called in
139+
* the same order as the `$scope.$broadcast` events are triggered, which is top down. This means that parent
140+
* components will have their `$onDestroy()` hook called before child components.
141+
* * `$postLink()` - Called after this controller's element and its children have been linked. Similar to the post-link
142+
* function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
143+
* Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
144+
* they are waiting for their template to load asynchronously and their own compilation and linking has been
145+
* suspended until that occurs.
146+
*
147+
* #### Comparison with Angular 2 life-cycle hooks
148+
* Angular 2 also uses life-cycle hooks for its components. While the Angular 1 life-cycle hooks are similar there are
149+
* some differences that you should be aware of, especially when it comes to moving your code from Angular 1 to Angular 2:
150+
*
151+
* * Angular 1 hooks are prefixed with `$`, such as `$onInit`. Angular 2 hooks are prefixed with `ng`, such as `ngOnInit`.
152+
* * Angular 1 hooks can be defined on the controller prototype or added to the controller inside its constructor.
153+
* In Angular 2 you can only define hooks on the prototype of the Component class.
154+
* * Due to the differences in change-detection, you may get many more calls to `$doCheck` in Angular 1 than you would to
155+
* `ngDoCheck` in Angular 2
156+
* * Changes to the model inside `$doCheck` will trigger new turns of the digest loop, which will cause the changes to be
157+
* propagated throughout the application.
158+
* Angular 2 does not allow the `ngDoCheck` hook to trigger a change outside of the component. It will either throw an
159+
* error or do nothing depending upon the state of `enableProdMode()`.
160+
*
161+
* #### Life-cycle hook examples
162+
*
163+
* This example shows how you can check for mutations to a Date object even though the identity of the object
164+
* has not changed.
165+
*
166+
* <example name="doCheckDateExample" module="do-check-module">
167+
* <file name="app.js">
168+
* angular.module('do-check-module', [])
169+
* .component('app', {
170+
* template:
171+
* 'Month: <input ng-model="$ctrl.month" ng-change="$ctrl.updateDate()">' +
172+
* 'Date: {{ $ctrl.date }}' +
173+
* '<test date="$ctrl.date"></test>',
174+
* controller: function() {
175+
* this.date = new Date();
176+
* this.month = this.date.getMonth();
177+
* this.updateDate = function() {
178+
* this.date.setMonth(this.month);
179+
* };
180+
* }
181+
* })
182+
* .component('test', {
183+
* bindings: { date: '<' },
184+
* template:
185+
* '<pre>{{ $ctrl.log | json }}</pre>',
186+
* controller: function() {
187+
* var previousValue;
188+
* this.log = [];
189+
* this.$doCheck = function() {
190+
* var currentValue = this.date && this.date.valueOf();
191+
* if (previousValue !== currentValue) {
192+
* this.log.push('doCheck: date mutated: ' + this.date);
193+
* previousValue = currentValue;
194+
* }
195+
* };
196+
* }
197+
* });
198+
* </file>
199+
* <file name="index.html">
200+
* <app></app>
201+
* </file>
202+
* </example>
203+
*
204+
* This example show how you might use `$doCheck` to trigger changes in your component's inputs even if the
205+
* actual identity of the component doesn't change. (Be aware that cloning and deep equality checks on large
206+
* arrays or objects can have a negative impact on your application performance)
207+
*
208+
* <example name="doCheckArrayExample" module="do-check-module">
209+
* <file name="index.html">
210+
* <div ng-init="items = []">
211+
* <button ng-click="items.push(items.length)">Add Item</button>
212+
* <button ng-click="items = []">Reset Items</button>
213+
* <pre>{{ items }}</pre>
214+
* <test items="items"></test>
215+
* </div>
216+
* </file>
217+
* <file name="app.js">
218+
* angular.module('do-check-module', [])
219+
* .component('test', {
220+
* bindings: { items: '<' },
221+
* template:
222+
* '<pre>{{ $ctrl.log | json }}</pre>',
223+
* controller: function() {
224+
* this.log = [];
225+
*
226+
* this.$doCheck = function() {
227+
* if (this.items_ref !== this.items) {
228+
* this.log.push('doCheck: items changed');
229+
* this.items_ref = this.items;
230+
* }
231+
* if (!angular.equals(this.items_clone, this.items)) {
232+
* this.log.push('doCheck: items mutated');
233+
* this.items_clone = angular.copy(this.items);
234+
* }
235+
* };
236+
* }
237+
* });
238+
* </file>
239+
* </example>
120240
*
121241
*
122242
* ### Directive Definition Object
@@ -292,110 +412,6 @@
292412
* The `$transclude` function also has a method on it, `$transclude.isSlotFilled(slotName)`, which returns
293413
* `true` if the specified slot contains content (i.e. one or more DOM nodes).
294414
*
295-
* The controller can provide the following methods that act as life-cycle hooks:
296-
* * `$onInit()` - Called on each controller after all the controllers on an element have been constructed and
297-
* had their bindings initialized (and before the pre &amp; post linking functions for the directives on
298-
* this element). This is a good place to put initialization code for your controller.
299-
* * `$onChanges(changesObj)` - Called whenever one-way (`<`) or interpolation (`@`) bindings are updated. The
300-
* `changesObj` is a hash whose keys are the names of the bound properties that have changed, and the values are an
301-
* object of the form `{ currentValue, previousValue, isFirstChange() }`. Use this hook to trigger updates within a
302-
* component such as cloning the bound value to prevent accidental mutation of the outer value.
303-
* * `$doCheck()` - Called on each turn of the digest cycle. Provides an opportunity to detect and act on
304-
* changes. Any actions that you wish to take in response to the changes that you detect must be
305-
* invoked from this hook; implementing this has no effect on when `$onChanges` is called. For example, this hook
306-
* could be useful if you wish to perform a deep equality check, or to check a Date object, changes to which would not
307-
* be detected by Angular's change detector and thus not trigger `$onChanges`. This hook is invoked with no arguments;
308-
* if detecting changes, you must store the previous value(s) for comparison to the current values.
309-
* * `$onDestroy()` - Called on a controller when its containing scope is destroyed. Use this hook for releasing
310-
* external resources, watches and event handlers. Note that components have their `$onDestroy()` hooks called in
311-
* the same order as the `$scope.$broadcast` events are triggered, which is top down. This means that parent
312-
* components will have their `$onDestroy()` hook called before child components.
313-
* * `$postLink()` - Called after this controller's element and its children have been linked. Similar to the post-link
314-
* function this hook can be used to set up DOM event handlers and do direct DOM manipulation.
315-
* Note that child elements that contain `templateUrl` directives will not have been compiled and linked since
316-
* they are waiting for their template to load asynchronously and their own compilation and linking has been
317-
* suspended until that occurs.
318-
*
319-
* ** $doCheck examples **
320-
*
321-
* This example shows how you can check for mutations to a Date object even though the identity of the object
322-
* has not changed.
323-
*
324-
* <example name="doCheckDateExample" module="do-check-module">
325-
* <file name="app.js">
326-
* angular.module('do-check-module', [])
327-
* .component('app', {
328-
* template:
329-
* 'Month: <input ng-model="$ctrl.month" ng-change="$ctrl.updateDate()">' +
330-
* 'Date: {{ $ctrl.date }}' +
331-
* '<test date="$ctrl.date"></test>',
332-
* controller: function() {
333-
* this.date = new Date();
334-
* this.month = this.date.getMonth();
335-
* this.updateDate = function() {
336-
* this.date.setMonth(this.month);
337-
* };
338-
* }
339-
* })
340-
* .component('test', {
341-
* bindings: { date: '<' },
342-
* template:
343-
* '<pre>{{ $ctrl.log | json }}</pre>',
344-
* controller: function() {
345-
* var previousValue;
346-
* this.log = [];
347-
* this.$doCheck = function() {
348-
* var currentValue = this.date && this.date.valueOf();
349-
* if (previousValue !== currentValue) {
350-
* this.log.push('doCheck: date mutated: ' + this.date);
351-
* previousValue = currentValue;
352-
* }
353-
* };
354-
* }
355-
* });
356-
* </file>
357-
* <file name="index.html">
358-
* <app></app>
359-
* </file>
360-
* </example>
361-
*
362-
* This example show how you might use `$doCheck` to trigger changes in your component's inputs even if the
363-
* actual identity of the component doesn't change. (Be aware that cloning and deep equality checks on large
364-
* arrays or objects can have a negative impact on your application performance)
365-
*
366-
* <example name="doCheckArrayExample" module="do-check-module">
367-
* <file name="index.html">
368-
* <div ng-init="items = []">
369-
* <button ng-click="items.push(items.length)">Add Item</button>
370-
* <button ng-click="items = []">Reset Items</button>
371-
* <pre>{{ items }}</pre>
372-
* <test items="items"></test>
373-
* </div>
374-
* </file>
375-
* <file name="app.js">
376-
* angular.module('do-check-module', [])
377-
* .component('test', {
378-
* bindings: { items: '<' },
379-
* template:
380-
* '<pre>{{ $ctrl.log | json }}</pre>',
381-
* controller: function() {
382-
* this.log = [];
383-
*
384-
* this.$doCheck = function() {
385-
* if (this.items_ref !== this.items) {
386-
* this.log.push('doCheck: items changed');
387-
* this.items_ref = this.items;
388-
* }
389-
* if (!angular.equals(this.items_clone, this.items)) {
390-
* this.log.push('doCheck: items mutated');
391-
* this.items_clone = angular.copy(this.items);
392-
* }
393-
* };
394-
* }
395-
* });
396-
* </file>
397-
* </example>
398-
*
399415
* #### `require`
400416
* Require another directive and inject its controller as the fourth argument to the linking function. The
401417
* `require` property can be a string, an array or an object:

0 commit comments

Comments
 (0)