> For the complete documentation index, see [llms.txt](https://jorgeucano.gitbook.io/entendiendo-angular/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jorgeucano.gitbook.io/entendiendo-angular/capitulo-7-componentes-avanzados/capitulo-6-componentes-avanzados.md).

# 7 - Componentes Avanzados

Ya estuvimos hablando de los componentes, y sabemos que son la gran mayoria de lo que vamos a escribir... porque deberiamos pensar en componentes.. Angular es un arbol de componentes, por lo tanto vamos a ver un poco mas a fondo todavia los componentes y entender un poco mas su integración.

```
import { Component } from '@angular/core';

@Component({
    selector: 'login',
    templateUrl: 'login.component.html'
})
export class LoginComponent{

    //contructor es quien recibe la inyeccion de las dependencias => capítulo 9
    constructor(){

    }


    // lifeCycle => capítulo 10
    ngOnInit(){
    }
    ngOnDestroy() {
    }


}
```

Vimos como crear un componente, agregarle entradas, salidas... pero hay mucho mas todavía.. vamos a ver/pensar todo lo que podemos hacer con un Componente...

Primero , el componente principal va a ser quien cargue la aplicación,

* Por medio de los lifecycle vamos a poder modificar cosas ( o determinar si se abre o no )&#x20;
* Por medio de router vamos a poder abrir componentes dentro de otros (sin que sean childcomponents, expecificamente)
* Vamos a poder pasar datos entre componentes padres e hijos (cuantos tengamos en la rama)
* Vamos a poder manejar distintos tipos de estados
* Vamos a poder pasar datos por medio de la Inyección de dependencias ( servicios )&#x20;
* Generar funcionalidad encapsulada
* manejo de formularios
* Manejo de eventos en la UI
* Detección de cambios (AngularZone)

Claro podemos hacer muchisimas cosas y todo eso gracias a toda la funcionalidad de Angular, y para eso vamos a tener que avazar con los capitulos ... pero queria mostrar como quedaria un componente super completo, mas alla que podrias no entender/saber algunas cosas de las que vamos a ver ahora, pero si podrias identificarlas.

```
import { Component, NgZone } from '@angular/core';

import { FormBuilder, FormGroup } from '@angular/forms';

import { Store } from '@ngrx/store';
import { INCREMENT, DECREMENT, RESET } from './services/counter';
import { Observable } from 'rxjs/Observable';

import { Router } from '@angular/router';

import { AngularFire, FirebaseListObservable } from 'angularfire2';
import { AuthProviders, AuthMethods } from 'angularfire2';

interface AppState{
  counter: number;
}

@Component({
  selector: 'app-component',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app works!';
  votacion = '';
  data:any;
  myForm : FormGroup;
  counter: Observable<number>;
  dataFirebase:any;
  errorMessage:any;

  constructor(
    private fb: FormBuilder,
    private store: Store<AppState>,
    private _ngZone:NgZone,
    private router: Router,
    private af : AngularFire
    ){

      this.callTicketsMongo();

      this.ticketFirebase = af.database.list('/ticket');

      this.dataFirebase.push({
          'id': 1, 'texto': 'no me funciona nada', 'estado': 'enojado'
      });


      this.af.auth.login({
        provider: AuthProviders.Google,
        method: AuthMethods.Popup
      });

      this.counter = store.select('counter');

    this.tickets = ticketService.getTickets();

    this.myForm = fb.group({
      'name': ['Jorge']
    });

  }

  callTicketsMongo():void{
    this.ticketService.getTicketsMongo()
        .then(
          tickets => this.ticketMongo = tickets,
          error => this.errorMessage = <any>error
        );
  }

  votos = [
    {title : 'Opción 1'},
    {title : 'Opción 2'},
    {title : 'Opción 3'},
    {title : 'Opción 4'}
  ];

  addVoto(response: string) {
    this.votacion = "Usted eligio: " + response;
  }

  cantidad = 5;
  factor = 1;

  onSubmit(value:string):void{
    console.log("El formulario tiene", value);
  }

  increment(){
    this.store.dispatch({type: INCREMENT});
  }

  decrement(){
    this.store.dispatch({type: DECREMENT});
  }
  reset(){
    this.store.dispatch({type: RESET});
  }

  progress: number = 0;
  label:string;

  processWithinAngularZone(){
    this.label="inside";
    this.progress = 0;
    this._ngZone.runOutsideAngular(()=>{
      this._increaseProgress(()=>{
        this._ngZone.run(()=>{console.log("Finalizado con ngzone")})
      })
    })
  }
  _increaseProgress(doneCallBack: ()=>void){
    this.progress+=1;
    console.log(`Progreso: ${this.progress}%`);
    if(this.progress<100){
      window.setTimeout(()=>{
        this._increaseProgress(doneCallBack);
      },10);
    }
    else{
      doneCallBack();
    }
  }

  verDatos(id:number):void{
     this.router.navigate(['/ticket', id ]);
  }  

  updateDatos(key):void{
    console.log(key);
    this.datosFirebase.update(key, {estado: 'avanzado'});
  }

  removeDatos(key):void{
    console.log(key);
    this.datosFirebase.remove(key);
  }

  removeAllTicket():void{
    this.datosFirebase.remove();
  }
}
```

Claro esto se esta poniendo interesante ( a decir verdad, este componente hasta podria ser "chico" comparado con otros), hay muchas mas funcionalidades en esta porción de código, pero no siempre es necesario tener todo ahi... ***seguramente mucho lo podriamos abstraer en otro componente***... por lo tanto es importante entender lo siguiente:

> ## Los componentes deben cumplir una función única, si tiene mas de una se pueden hacer dos componentes (uno podria ser hijo del otro)

***Importante: Este capítulo va a estar siempre en modo WIP (work in progress) ya que angular va a ir avanzado y este capítulo va a estar para esos avances, la idea de este capitulo es que entiendan que apartir de ahora vamos a agregar un monton de funcionalidad que puede estar en un solo componente o entender que podemos utilizar la "atomicidad" y poder reutilizar todos los componentes que realicemos para nuestros desarrollos.***
