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. class PessoaComponent implements ng.IComponentOptions {
  3. bindings: { [binding: string]: string };
  4. controller = App.Pessoa.PessoaComponentController;
  5. templateUrl = ['util', '$attrs', (util: App.IUtilProvider, $attrs: ng.IAttributes) => {
  6. return util.buildTemplateUrl('pessoa/pessoa', $attrs['layout'] || '');
  7. }];
  8. constructor() {
  9. this.bindings = {
  10. model: '<',
  11. onEvent: '&'
  12. };
  13. }
  14. }
  15. angular
  16. .module('app.pessoa')
  17. .component('fslPessoa', new PessoaComponent());
  18. })();
The Angular component's Controller.
  1. namespace App.Pessoa {
  2. export class PessoaComponentController implements ng.IComponentController {
  3. model: App.Pessoa.IPessoa | App.Pessoa.IPessoa[];
  4. pessoa: App.Pessoa.IPessoa;
  5. pessoas: App.Pessoa.IPessoa[];
  6. onEvent: (values: any) => void;
  7. constructor(
  8. private util: App.IUtilProvider
  9. ) {
  10. }
  11. $onInit = () => {
  12. this.receberModel(this.model);
  13. }
  14. $onChanges = (changes) => {
  15. if (!changes.model.isFirstChange()) {
  16. this.receberModel(changes.model.currentValue);
  17. }
  18. }
  19. incluirPessoa = () => {
  20. var pessoa = this.criarNovaPessoa();
  21. this.pessoas.push(pessoa);
  22. this.dispararEvento("incluir", pessoa);
  23. }
  24. excluirPessoa = (pessoa: App.Pessoa.IPessoa) => {
  25. var index = this.pessoas.indexOf(pessoa);
  26. this.pessoas.splice(index, 1);
  27. this.dispararEvento("excluir", pessoa);
  28. }
  29. editarPessoa = (pessoa: App.Pessoa.IPessoa) => {
  30. this.dispararEvento("editar", pessoa);
  31. }
  32. salvarPessoa = () => {
  33. this.dispararEvento("salvar", this.pessoa);
  34. this.pessoa = this.criarNovaPessoa();
  35. }
  36. private criarNovaPessoa = () => {
  37. return {
  38. id: this.util.generateGuid()
  39. }
  40. }
  41. private dispararEvento = (evento: string, pessoa: App.Pessoa.IPessoa, index?: number) => {
  42. if (angular.isDefined(this.onEvent)) {
  43. this.onEvent({ pessoa: pessoa, evento: evento, index: index });
  44. }
  45. }
  46. private receberModel = (model: App.Pessoa.IPessoa | App.Pessoa.IPessoa[]) => {
  47. if (model) {
  48. if (angular.isArray(model)) {
  49. this.pessoas = <App.Pessoa.IPessoa[]>model;
  50. } else {
  51. angular.copy(<App.Pessoa.IPessoa>model, this.pessoa);
  52. }
  53. }
  54. this.pessoa = this.pessoa || this.criarNovaPessoa();
  55. this.pessoas = this.pessoas || [];
  56. }
  57. }
  58. PessoaComponentController.$inject = [
  59. 'util'
  60. ];
  61. }
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. console.log(evento, this.pessoa);
  3. }
From here, you can download full source code.