angular tutorial

Volviendo con un poco de angular, me salio la necesidad de crear un reloj en angular, para esto necesitamos conocer unos conceptos básicos de rxjs.

Porque usar rxjs y no un interval

Una de las maneras mas sencillas es usar un setInterval de javascript que cada segundo ejecuta una función y bueno ya tenemos un reloj, pero para no romper la armonía de angular y dejar de usar el hilo principal vamos a usar Observables y un evento llamado timer.

Como ya sabemos el Observable lo que hace es que usa un hilo asíncrono para hacer una tarea especifica y te avisa cuando existe un cambio.

timer seria como un interval en rx, le decimos cada cuanto va a ejecutarse y lo repite cada x tiempo.

como podemos ver tenemos un reloj digital para esto vamos a hacer un servicio para podernos suscribirnos y tener la información de la fecha y hora.

Creación de reloj en angular

para el servicio vamos a crear lo siguiente:

  • modelo para información de datos (hora, día y fecha)
  • VARIABLES Observables
  • llenar variables y conversión a objeto observable

Servicio de reloj

import { Injectable } from '@angular/core';
import {timer, Observable, Subject} from 'rxjs';
import {map, shareReplay} from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class valorReloj {
  hora: number;
  minutos: string;
  ampm: string;
  diadesemana: string;
  diaymes: string;
  segundo: string;
}
export class XsegundoService {
  clock: Observable <Date>;
  infofecha$ = new Subject<valorReloj>();
  vr: valorReloj;
  ampm: string;
  hours: number;
  minute: string;
  weekday: string;
  months: string;


  constructor() {
    this.clock = timer(0,1000).pipe(map(t => new Date()),shareReplay(1));

   }
   getInfoReloj(): Observable<valorReloj>{
     this.clock.subscribe(t => {
      this.hours = t.getHours() % 12;
      this.hours = this.hours ? this.hours : 12;
       this.vr = {
         hora: this.hours,
         minutos: (t.getMinutes() < 10) ? '0' + t.getMinutes() : t.getMinutes().toString(),
         ampm: t.getHours() > 11 ? 'PM' : 'AM',
         diaymes: t.toLocaleString('es-MX', { day: '2-digit', month: 'long' }).replace('.', '').replace('-', ' '),
         diadesemana: t.toLocaleString('es-MX', { weekday: 'long' }).replace('.', ''),
         segundo: t.getSeconds() < 10 ? '0' + t.getSeconds() : t.getSeconds().toString()

       }
       this.infofecha$.next(this.vr);
     });
     return this.infofecha$.asObservable();

   }
}

tenemos que recordar lo siguiente, pueden leer este articulo, pero en resumen:

  • subject: que es el encargado de generar y emitir los eventos de actualización del almacén de datos.
  • observable: es un objeto que permite observar los eventos emitidos por el subject.
  • suscripción: generada a partir del observable.
  • shareReplay: pueden suscribirse y enviara la ultima información a los suscritos para que no exista un retraso
  • toLocaleString:
    retorna una cadena que contiene una representación del número acorde al idioma.
  • next: avisa a observador que existe un cambio
  • variable$: una variable con el signo $ indica que es un observable

con esto ya podemos suscribirnos en cualquier parte y poder crear un reloj en angular.

Al ser un Date, nos trae hora , minutos, segundos, fecha, dia y año, lo que hice fue un modelo y extraje lo que mas me interesaba y en formato de 12 horas.

vista del componente clock.

<div class="clock">
    <p>{{dia}}</p>
    <p>{{fecha}}</p>
    <div class="hours">
        <div class="horas">
            <span class="mishoras">{{hora}}:{{minutos}}</span>
            <span class="ampm">{{ampm}}</span>
        </div>
    </div>
    <div></div>
    <span></span>
    <span class="segundos">{{segundos}}</span>
</div>

css

.clock {
    display: grid;
    grid-gap: 1px 5px;
    grid-template-columns: auto auto auto;
    justify-content: center;
    align-content: center;
    align-items: center;
    align-self: center;
    width: 100%;
}

.clock p {
    color: #666;
    font-size: 2rem;
}

.hours {
    grid-column-start: 1;
    grid-column-end: 3;
}

.horas {
    display: flex;
    flex-wrap: nowrap;
    flex-direction: column-reverse;
    justify-content: center;
    align-items: baseline;
}

span {
    color: #777777;
}

.mishoras {
    font-weight: bold;
    font-size: 10rem;
}

.ampm {
    font-size: 1.4rem;
    font-weight: 200;
}

.segundos {
    width: 100%;
    text-align: right;
    font-size: 0.8rem;
    font-size: 100;
}

Como llamar nuestro servicio para crear un reloj en angular 7

import { Component, OnInit } from '@angular/core';
import {XsegundoService, valorReloj} from '../xsegundo.service';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-clock',
  templateUrl: './clock.component.html',
  styleUrls: ['./clock.component.css']
})
export class ClockComponent implements OnInit {
  datos$: Observable<valorReloj>;
  hora: number;
  minutos: string;
  dia: string;
  fecha: string;
  ampm: string;
  segundos: string;


  constructor(private segundo: XsegundoService) { }

  ngOnInit() {
    this.datos$=this.segundo.getInfoReloj();
    this.datos$.subscribe(x => {
      this.hora = x.hora;
      this.minutos = x.minutos;
      this.dia = x.diadesemana;
      this.fecha = x.diaymes;
      this.ampm = x.ampm;
      this.segundos = x.segundo
    });
  }

}

al ser un observable la función getInfoReloj nos regresara un cambio cada segundo (recuerden que así configuramos el timer) y para obtener el objeto que manda tenemos que suscribirnos a ellos.

al final solo llamamos a nuestro componente

<app-clock class="mreloj"></app-clock>

Como es costumbre dejare los links del repositorio y del post en live

por Cesar Flores

Programador de tiempo completo, Gamer de medio tiempo y fotógrafo ocasionalmente, me gusta el front-end y mi framework favorito es angular aunque no por eso le hago el feo a un nuevo lenguaje.

2 comentario en “Crear un reloj en angular 7”

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.