Angular Component With TypeScript

What is the goal?
  1. Use of Angular Components with multiple templates.
  2. Usage of TypeScript for productivity.
  3. Calling the components in different ways.
I won't write all the code here. Instead, you can download the full source code from the link mentioned at the end of this article.
 
Let's get started!
 
Here, person is a component. You can edit, insert or view that person. The same component can have multiples views.
 
The component is created using the list layout.
  1. <fsl-pessoa layout="lista-edicao"  
  2.                         model="$ctrl.pessoas"  
  3.                         on-event="$ctrl.onChanges(pessoa, evento, index)"></fsl-pessoa>   
Each component has some properties.
  1. "layout" - the layout name for component. There are two layouts: one is the list of persons; second is the edit of a person.
  2. "model" - the object model to populate the component.
  3. "on-event" - the change event of the component.  
The component using the edit layout. 
  1. <fsl-pessoa layout="edicao"  
  2.                         model="$ctrl.pessoa"  
  3.                         on-event="$ctrl.onChanges(pessoa, evento, index)"></fsl-pessoa>  
Defining the Angular Component.
  1. (() => {  
  2.   
  3.     class PessoaComponent implements ng.IComponentOptions {  
  4.   
  5.         bindings: { [binding: string]: string };  
  6.         controller = App.Pessoa.PessoaComponentController;  
  7.   
  8.         templateUrl = ['util''$attrs', (util: App.IUtilProvider, $attrs: ng.IAttributes) => {  
  9.             return util.buildTemplateUrl('pessoa/pessoa', $attrs['layout'] || '');  
  10.         }];  
  11.   
  12.         constructor() {  
  13.             this.bindings = {  
  14.                 model: '<',  
  15.                 onEvent: '&'  
  16.             };  
  17.         }  
  18.   
  19.     }  
  20.   
  21.     angular  
  22.         .module('app.pessoa')  
  23.         .component('fslPessoa'new PessoaComponent());  
  24.   
  25. })();   
The Angular component's Controller. 
  1. namespace App.Pessoa {  
  2.   
  3.     export class PessoaComponentController implements ng.IComponentController {  
  4.   
  5.         model: App.Pessoa.IPessoa | App.Pessoa.IPessoa[];  
  6.         pessoa: App.Pessoa.IPessoa;  
  7.         pessoas: App.Pessoa.IPessoa[];  
  8.         onEvent: (values: any) => void;  
  9.   
  10.         constructor(  
  11.             private util: App.IUtilProvider  
  12.         ) {  
  13.   
  14.         }  
  15.           
  16.         $onInit = () => {  
  17.             this.receberModel(this.model);  
  18.         }  
  19.                   
  20.         $onChanges = (changes) => {  
  21.             if (!changes.model.isFirstChange()) {  
  22.                 this.receberModel(changes.model.currentValue);  
  23.             }  
  24.         }  
  25.   
  26.         incluirPessoa = () => {  
  27.             var pessoa = this.criarNovaPessoa();  
  28.             this.pessoas.push(pessoa);  
  29.             this.dispararEvento("incluir", pessoa);  
  30.         }  
  31.   
  32.         excluirPessoa = (pessoa: App.Pessoa.IPessoa) => {  
  33.             var index = this.pessoas.indexOf(pessoa);  
  34.             this.pessoas.splice(index, 1);  
  35.             this.dispararEvento("excluir", pessoa);  
  36.         }  
  37.   
  38.         editarPessoa = (pessoa: App.Pessoa.IPessoa) => {  
  39.             this.dispararEvento("editar", pessoa);  
  40.         }  
  41.   
  42.         salvarPessoa = () => {  
  43.             this.dispararEvento("salvar"this.pessoa);  
  44.             this.pessoa = this.criarNovaPessoa();  
  45.         }  
  46.   
  47.         private criarNovaPessoa = () => {  
  48.             return {  
  49.                 id: this.util.generateGuid()  
  50.             }  
  51.         }  
  52.   
  53.         private dispararEvento = (evento: string, pessoa: App.Pessoa.IPessoa, index?: number) => {  
  54.             if (angular.isDefined(this.onEvent)) {  
  55.                 this.onEvent({ pessoa: pessoa, evento: evento, index: index });  
  56.             }  
  57.         }  
  58.   
  59.         private receberModel = (model: App.Pessoa.IPessoa | App.Pessoa.IPessoa[]) => {  
  60.             if (model) {  
  61.                 if (angular.isArray(model)) {  
  62.                     this.pessoas = <App.Pessoa.IPessoa[]>model;  
  63.                 } else {  
  64.                     angular.copy(<App.Pessoa.IPessoa>model, this.pessoa);  
  65.                 }  
  66.             }  
  67.   
  68.             this.pessoa = this.pessoa || this.criarNovaPessoa();  
  69.             this.pessoas = this.pessoas || [];  
  70.         }  
  71.   
  72.     }  
  73.   
  74.     PessoaComponentController.$inject = [  
  75.         'util'  
  76.     ];  
  77.   
  78. }   
Basically, Angular component best practices must be.
  1. Stateless don't change the model outside the component
  2. Events if any changes occusr inside a component, fire them using events
  3. Reusable create the component to be reusable anywhere
The Angular Life Cycle events*.
  1. "constructor" in the creation;
  2. $onInit in first init;
  3. $onChanges when the model changes inside or outside the component;  
There are other events. For more information, please check Angular API reference. 
 
Very Important
 
In the component (code), fire the custom event passing the parameters inside an object. 
  1. this.onEvent({ pessoa: pessoa, evento: evento, index: index });  
In usage of component (html), declare the custom event using the same parameter name and order. 
  1. on-event="$ctrl.onChanges(pessoa, evento, index)"  
In code callback (code), receive the custom event using the same parameter name and order. 
  1. onChanges = (pessoa: App.Pessoa.IPessoa, evento: string) => {  
  2.             
  3.    console.log(evento, this.pessoa); 
  4.  
  5. }    
From here, you can download full source code