'
+ ].join(''),
+ properties: ['title']
+ })
+ .Class({
+ constructor: function(){},
+
+ ngOnInit: function(){
+ this.model = { };
+ this.model.title = this.currentTitle = this.title;
+ this.noChangeCount = 0;
+ this.changeDetected = null;
+ },
+
+ ngDoCheck: function(){
+ if (this.model.title !== this.currentTitle) {
+ this.changeDetected = true;
+
+ console.log('ngDoCheck: Title changed to ' + this.model.title + ' from ' + this.currentTitle);
+
+ this.currentTitle = this.model.title;
+ }
+
+ if (this.changeDetected) { this.noChangeCount = 0; }
+ else if (this.changeDetected === false) {
+ this.noChangeCount++;
+ console.log('ngDoCheck: called ' + this.noChangeCount + 'x when no change to title');
+ }
+
+ this.changeDetected = false;
+ }
+ });`;
+}
+
+function getNgAfterContent01(){
+ return `
+ import * as ngCore from '@angular/core';
+
+ import { titleComponent } from './title.component';
+ import { itemComponent } from './item.component';
+
+ export var childComponent = ngCore.Component({
+ selector: 'my-child',
+ template: '',
+ queries: {
+ title: new ngCore.ContentChild(titleComponent),
+ items: new ngCore.ContentChildren(itemComponent)
+ }
+ })
+ .Class({
+ constructor: function(){},
+
+ ngAfterContentInit: function(){
+ //title & items will be available since there
+ console.log('title', this.title);
+ console.log('items', this.items);
+ },
+
+ ngAfterContentChecked: function(){
+ // If there're changes to contentChild
+ // contentChild is updated at there after the content has been checked
+ // This event is fired after every check of projected component content
+ }
+ });`;
+}
+
+function getNgAfterContent02(){
+ return `
+ import * as ngCore from '@angular/core';
+
+ import { childComponent } from './child.component';
+ import { titleComponent } from './title.component';
+ import { itemComponent } from './item.component';
+
+ export var ngAfterContentComponent = ngCore.Component({
+ selector: 'my-example',
+ template: [
+ '',
+ '',
+ '',
+ ''
+ ].join(''),
+ directives: [
+ childComponent,
+ titleComponent,
+ itemComponent
+ ]
+ })
+ .Class({
+ constructor: function(){},
+
+ ngOnInit: function() {
+ this.title = 'ngAfterContent';
+ this.items = [
+ { id: 1, name: 'item 01' },
+ { id: 2, name: 'item 02' }
+ ];
+ }
+ });`;
+}
+
+function getNgAfterView(){
+ return `
+ import * as ngCore from '@angular/core';
+
+ import { childComponent } from './child.component';
+
+ export var ngAfterViewComponent = ngCore.Component({
+ selector: 'my-example',
+ template: [
+ '',
+ '',
+ '
ngAfterViewChecked is fired: {{noChangeCount}}x
'
+ ].join(''),
+ directives: [ childComponent ],
+ queries: {
+ title: new ngCore.ViewChild('title', { read: ngCore.ElementRef }),
+ childs: new ngCore.ViewChildren(childComponent)
+ }
+ })
+ .Class({
+ constructor: function(){},
+
+ ngOnInit: function() {
+ this.items = [
+ { id: 1, name: 'item 01' },
+ { id: 2, name: 'item 02' }
+ ];
+ this.noChangeCount = 0;
+ },
+
+ ngAfterViewInit: function(){
+ //title & childs will be available since there
+ this.title.nativeElement.innerHTML = 'ngAfterView';
+ console.log('title', this.title.nativeElement);
+ console.log('childs', this.items);
+ },
+
+ ngAfterViewChecked: function(){
+ // If there're changes to ViewChild
+ // ViewChild is updated at there after the view has been checked
+ // This event is fired after every check of the component's views and child views.
+ var _self = this;
+ setTimeout(function(){
+ if(!_self.noChangeCount){ _self.noChangeCount++; }
+ });
+ }
+ });`;
+}
\ No newline at end of file
diff --git a/cms/articles/1473861890/article-1473861890.component.js b/cms/articles/1473861890/article-1473861890.component.js
new file mode 100644
index 0000000..c5852a6
--- /dev/null
+++ b/cms/articles/1473861890/article-1473861890.component.js
@@ -0,0 +1,341 @@
+import { Component } from '@angular/core';
+import { DomSanitizer } from '@angular/platform-browser';
+import highlight from 'highlight.js';
+
+import { xblogTableContentService } from 'xblog-cores/modules';
+import { resourceUtils } from 'xblog-cores/utils';
+
+
+export var article1473861890Component = Component({
+ selector: 'article',
+ template: "
In previous articles, you've alreadry gotten knowledges about directives/components.
Go on with a subject relate to them, I'll show you their lifecycle.
A component has a lifecycle managed by Angular itself.
Angular offers component lifecycle hooks that give us the ability to act when they occur.
No directive or component will implement all of them and some of the hooks only make sense for components.
After component's constructor is called to create an instance, Angular calls its lifecycle hook methods in following sequence.
Angular only calls a hook method if it is defined.
HooksTimingngOnChangesBefore ngOnInit and when a data-bound input property value changes.ngOnInitAfter the first ngOnChanges.ngDoCheckDuring every Angular change detection cycle.ngAfterContentInitAfter projecting content into the component.ngAfterContentCheckedAfter every check of projected component content.ngAfterViewInitAfter initializing the component's views and child views.ngAfterViewCheckedAfter every check of the component's views and child views.ngOnDestroyJust before Angular destroys the directive/component.
We'll detail each lifecycle hook and find out how we should work with them.
Table of Contents
ngOnChanges
This hook method executes before ngOnInit and when a data-bound input property value changes.
The method receives a object of current and previous values, I call it is changeRecord.
For example, I have ngOnChangesComponent as below.
If you try to update component's data-bound property immediately instead of using setTimeout, Angular throws an error.
Notice that we must adhere to Angular's unidirectional data flow rule which says that we may not update the view after it has been composed.
Both hooks fire after the component's view has been composed.
For ngAfterViewChecked, Angular frequently calls it, even when there are no changes of interest. Write lean hook methods to avoid performance problems.
ngOnDestroy
This hook run just before Angular destroys the directive/component.
This is the place to free resources that won't be garbage collected automatically such as unsubscribe from observables and DOM events, stop interval timers etc.
'
+ ].join(''),
+ properties: ['title']
+ })
+ .Class({
+ constructor: function(){},
+
+ ngOnInit: function(){
+ this.model = { };
+ this.model.title = this.currentTitle = this.title;
+ this.noChangeCount = 0;
+ this.changeDetected = null;
+ },
+
+ ngDoCheck: function(){
+ if (this.model.title !== this.currentTitle) {
+ this.changeDetected = true;
+
+ console.log('ngDoCheck: Title changed to ' + this.model.title + ' from ' + this.currentTitle);
+
+ this.currentTitle = this.model.title;
+ }
+
+ if (this.changeDetected) { this.noChangeCount = 0; }
+ else if (this.changeDetected === false) {
+ this.noChangeCount++;
+ console.log('ngDoCheck: called ' + this.noChangeCount + 'x when no change to title');
+ }
+
+ this.changeDetected = false;
+ }
+ });`;
+}
+
+function getNgAfterContent01(){
+ return `
+ import * as ngCore from '@angular/core';
+
+ import { titleComponent } from './title.component';
+ import { itemComponent } from './item.component';
+
+ export var childComponent = ngCore.Component({
+ selector: 'my-child',
+ template: '',
+ queries: {
+ title: new ngCore.ContentChild(titleComponent),
+ items: new ngCore.ContentChildren(itemComponent)
+ }
+ })
+ .Class({
+ constructor: function(){},
+
+ ngAfterContentInit: function(){
+ //title & items will be available since there
+ console.log('title', this.title);
+ console.log('items', this.items);
+ },
+
+ ngAfterContentChecked: function(){
+ // If there're changes to contentChild
+ // contentChild is updated at there after the content has been checked
+ // This event is fired after every check of projected component content
+ }
+ });`;
+}
+
+function getNgAfterContent02(){
+ return `
+ import * as ngCore from '@angular/core';
+
+ import { childComponent } from './child.component';
+ import { titleComponent } from './title.component';
+ import { itemComponent } from './item.component';
+
+ export var ngAfterContentComponent = ngCore.Component({
+ selector: 'my-example',
+ template: [
+ '',
+ '',
+ '',
+ ''
+ ].join(''),
+ directives: [
+ childComponent,
+ titleComponent,
+ itemComponent
+ ]
+ })
+ .Class({
+ constructor: function(){},
+
+ ngOnInit: function() {
+ this.title = 'ngAfterContent';
+ this.items = [
+ { id: 1, name: 'item 01' },
+ { id: 2, name: 'item 02' }
+ ];
+ }
+ });`;
+}
+
+function getNgAfterView(){
+ return `
+ import * as ngCore from '@angular/core';
+
+ import { childComponent } from './child.component';
+
+ export var ngAfterViewComponent = ngCore.Component({
+ selector: 'my-example',
+ template: [
+ '',
+ '',
+ '
ngAfterViewChecked is fired: {{noChangeCount}}x
'
+ ].join(''),
+ directives: [ childComponent ],
+ queries: {
+ title: new ngCore.ViewChild('title', { read: ngCore.ElementRef }),
+ childs: new ngCore.ViewChildren(childComponent)
+ }
+ })
+ .Class({
+ constructor: function(){},
+
+ ngOnInit: function() {
+ this.items = [
+ { id: 1, name: 'item 01' },
+ { id: 2, name: 'item 02' }
+ ];
+ this.noChangeCount = 0;
+ },
+
+ ngAfterViewInit: function(){
+ //title & childs will be available since there
+ this.title.nativeElement.innerHTML = 'ngAfterView';
+ console.log('title', this.title.nativeElement);
+ console.log('childs', this.items);
+ },
+
+ ngAfterViewChecked: function(){
+ // If there're changes to ViewChild
+ // ViewChild is updated at there after the view has been checked
+ // This event is fired after every check of the component's views and child views.
+ var _self = this;
+ setTimeout(function(){
+ if(!_self.noChangeCount){ _self.noChangeCount++; }
+ });
+ }
+ });`;
+}
\ No newline at end of file
diff --git a/cms/articles/1473861890/article-1473861890.component.prebuild.json b/cms/articles/1473861890/article-1473861890.component.prebuild.json
new file mode 100644
index 0000000..84e75cb
--- /dev/null
+++ b/cms/articles/1473861890/article-1473861890.component.prebuild.json
@@ -0,0 +1,4 @@
+{
+ "origin": "./cms/articles/1473861890/_article-1473861890.component.js",
+ "inline": "./cms/articles/1473861890/article-1473861890.component.js"
+}
\ No newline at end of file
diff --git a/cms/articles/1473861890/index.js b/cms/articles/1473861890/index.js
new file mode 100644
index 0000000..5de551c
--- /dev/null
+++ b/cms/articles/1473861890/index.js
@@ -0,0 +1,15 @@
+import { resourceUtils } from 'xblog-cores/utils';
+import { article1473861890Component } from './article-1473861890.component';
+
+export var article1473861890 = {
+ id: 1473861890,
+ title: 'Component Lifecycle In Angular 2',
+ postedDate: 'Wed Sep 14 2016 21:04:49 GMT+0700 (SE Asia Standard Time)',
+ author: 'Minh Van',
+ cover: resourceUtils.getImg('xblog-home-cover.jpg'),
+ routeLink: resourceUtils.getArticleRouteLink('component-lifecycle-in-angular-2-1473861890.html'),
+ relatedArticles: [],
+ tags: [],
+ description: 'A component has a lifecycle managed by Angular itself. Angular offers component lifecycle hooks that give us the ability to act when they occur.',
+ content: article1473861890Component,
+};
diff --git a/cms/articles/1473861890/resources/images/ngAfterContent-example-1473861890.png b/cms/articles/1473861890/resources/images/ngAfterContent-example-1473861890.png
new file mode 100644
index 0000000..0bfbcb5
Binary files /dev/null and b/cms/articles/1473861890/resources/images/ngAfterContent-example-1473861890.png differ
diff --git a/cms/articles/1473861890/resources/images/ngAfterView-example-1473861890.png b/cms/articles/1473861890/resources/images/ngAfterView-example-1473861890.png
new file mode 100644
index 0000000..9d70c02
Binary files /dev/null and b/cms/articles/1473861890/resources/images/ngAfterView-example-1473861890.png differ
diff --git a/cms/articles/1473861890/resources/images/ngDoCheck-example-1473861890.png b/cms/articles/1473861890/resources/images/ngDoCheck-example-1473861890.png
new file mode 100644
index 0000000..1eb3601
Binary files /dev/null and b/cms/articles/1473861890/resources/images/ngDoCheck-example-1473861890.png differ
diff --git a/cms/articles/1473861890/resources/images/ngOnChanges-example-1473861890.png b/cms/articles/1473861890/resources/images/ngOnChanges-example-1473861890.png
new file mode 100644
index 0000000..2187f8f
Binary files /dev/null and b/cms/articles/1473861890/resources/images/ngOnChanges-example-1473861890.png differ
diff --git a/cms/articles/1473861890/resources/images/ngOnInit-example-1473861890.png b/cms/articles/1473861890/resources/images/ngOnInit-example-1473861890.png
new file mode 100644
index 0000000..3a154f7
Binary files /dev/null and b/cms/articles/1473861890/resources/images/ngOnInit-example-1473861890.png differ
diff --git a/cms/articles/1473861890/templates/article-1473861890.html b/cms/articles/1473861890/templates/article-1473861890.html
new file mode 100644
index 0000000..454f22d
--- /dev/null
+++ b/cms/articles/1473861890/templates/article-1473861890.html
@@ -0,0 +1,209 @@
+
In previous articles, you've alreadry gotten knowledges about directives/components.
+
Go on with a subject relate to them, I'll show you their lifecycle.
+
+
A component has a lifecycle managed by Angular itself.
+
Angular offers component lifecycle hooks that give us the ability to act when they occur.
+
No directive or component will implement all of them and some of the hooks only make sense for components.
+
+
After component's constructor is called to create an instance, Angular calls its lifecycle hook methods in following sequence.
+
Angular only calls a hook method if it is defined.
+
+
+
+
+ Hooks
+ Timing
+
+
+
+ ngOnChanges
+
+ Before ngOnInit and when a data-bound input property value changes.
+
+
+
+
+ ngOnInit
+
+ After the first ngOnChanges.
+
+
+
+
+ ngDoCheck
+
+ During every Angular change detection cycle.
+
+
+
+
+ ngAfterContentInit
+
+ After projecting content into the component.
+
+
+
+
+ ngAfterContentChecked
+
+ After every check of projected component content.
+
+
+
+
+ ngAfterViewInit
+
+ After initializing the component's views and child views.
+
+
+
+
+ ngAfterViewChecked
+
+ After every check of the component's views and child views.
+
+
+
+
+ ngOnDestroy
+
+ Just before Angular destroys the directive/component.
+
+
+
+
+
+
We'll detail each lifecycle hook and find out how we should work with them.
+
+
+
+
Table of Contents
+
+
+
+
ngOnChanges
+
This hook method executes before ngOnInit and when a data-bound input property value changes.
+
The method receives a object of current and previous values, I call it is changeRecord.
+
+
For example, I have ngOnChangesComponent as below.
If you try to update component's data-bound property immediately instead of using setTimeout, Angular throws an error.
+
+
Notice that we must adhere to Angular's unidirectional data flow rule which says that we may not update the view after it has been composed.
+
Both hooks fire after the component's view has been composed.
+
+
For ngAfterViewChecked, Angular frequently calls it, even when there are no changes of interest. Write lean hook methods to avoid performance problems.
+
+
ngOnDestroy
+
This hook run just before Angular destroys the directive/component.
+
This is the place to free resources that won't be garbage collected automatically such as unsubscribe from observables and DOM events, stop interval timers etc.
+
\ No newline at end of file
diff --git a/cms/articles/index.js b/cms/articles/index.js
index e1aafe3..1bc30a7 100644
--- a/cms/articles/index.js
+++ b/cms/articles/index.js
@@ -13,8 +13,11 @@ import {
xblogTableContentService
} from 'xblog-cores/modules';
-var _ARTICLES = [];
+import { article1473861890 } from './1473861890';
+var _ARTICLES = [
+ article1473861890
+];
export var ARTICLE_STORE = _init();
@@ -22,7 +25,6 @@ var _ARTICLE_COMPONENTS = ARTICLE_STORE.LIST.map(function(article){
return article.content;
});
-
export var cmsArticlesModuleMetadata = Class({
constructor: function cmsArticlesModuleMetadata(){
Object.assign(this, {