El propósito de esta entrada, es crear tu primera aplicación angular de manera fácil como simple introducción a esta tecnología, que ha invadido ya un importante porcentaje de las webs que visitamos cada día. En ella veremos una instalación al uso del entorno de desarrollo, codificación de una pequeña aplicación con la que podremos interactuar con elementos del navegador, y algunos conceptos de typescript, el lenguaje principal en el que delega Angular su funcionamiento.

¿Por qué Angular?

Al igual que cualquier otro framework, angular proporciona una mejora en la manera de desarrollar aplicaciones. Angular esta pensada para lidiar con muchas caracterísiticas molestas que contenía el desarrollo web anteriormente. Al igual que Angular, hay otros frameworks muy potentes con objetivos similares como React.js o Vue.js . Estos frameworks también nos facilitarán la creación y manipulación de interfaces web así como la conexión con servidores de backend.

Este tipo de frameworks modernos, tienen una serie de características muy interesantes y que crece cada día. Algunas de estas características son: creación de aplicaciones fuera de entorno web, facilidad para conseguir compatibilidad en ejecución en la mayoría de navegadores (ahorrándonos las incordiantes excepciones para muchos casos) y sobre todo, la simplificación de la manipulación de los elementos de la pantalla.

También cuenta con un acercamiento de la codificación a una metodología más parecida a la programación usada en entornos corporativa. Programación orientada a objetos, patrones de diseño más desarrollados como MVC, facilidad de testeo, inyección de dependencias, gestión de paquetes…

¿Qué haremos como primera aplicación Angular?

Vamos a hacer un pequeño TicTacToe (Tres en raya). Cómo es una entrada introductoria, no vamos a entrar en detalles de los comportamientos de Angular. Vamos a focalizarnos en cómo empezar a programar una aplicación, ejecutarla y poder ver la «simpleza» del proyecto resultante.

Instalación del entorno del desarrollo

Para empezar con nuestra aplicación, vamos a instalar lo siguiente:

  • Node.js – Nos descargaremos la última versión LTS que haya disponible para nuestro sistema operativo.
  • Angular CLI – Instalaremos angular cli para poder crear aplicaciones y generar partes de código de la aplicación.
  • Visual Studio Code – Para ediar los ficheros de texto donde programaremos. Puedes usar cualquier alternativa, Notepad++, Sublime…

Lo primero, instalaremos el entorno de Node.js en nuestra máquina, a partir del instalable que descarguemos de su web oficial. Esto nos proporciona un motor de ejecución en nuestra máquina donde ejecutar código JavaScript. Con la instalación de Node, habremos instalado también una de sus herramientas principales, el Node Package Manager, popularmente conocido como npm. Con este instalador de paquetes podremos instalar Angular, React o cualquier otro framework basado en NodeJS.

Para comprobar que esté realmente instalado, abrimos una consola en nuestra máquina y comprobamos la aplicación de node consultando su versión:

PS C:\Users\Juan\Desktop\AngularTests> node -v
v16.15.1

Esta es la versión actual a día de escritura de este post, por lo que seguramente sea distinta cuando estés leyendo esto.

Tras esto, vamos a instalar Angular CLI, usando el package manager de node.

PS C:\Users\Juan\Desktop\AngularTests> npm install -g @angular/cli
npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.
npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.

added 219 packages, and audited 220 packages in 32s

25 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
npm notice
npm notice New minor version of npm available! 8.11.0 -> 8.12.2
npm notice Changelog: https://github.com/npm/cli/releases/tag/v8.12.2
npm notice Run npm install -g npm@8.12.2 to update!
npm notice

Podemos ver que hemos instalado 219 paquetes y que hay una nueva versión de npm disponible. Podríamos haber actualizado npm justo antes de hacer la instalación (pero un mundo sin rebeldes no es un mundo feliz) ejecutando el comando que nos propone angular en la misma consola.

Como último paso de nuestra instalación de entorno de desarrollo, vamos a lanzar el comando para crear el proyecto. Esto nos permitirá crear tu primera aplicación Angular. Ese proyecto se creará en la ruta donde estemos situados en la consola, así que recuerda moverte donde necesites crearlo. Los comandos del cliente de Angular se lanzan usando la aplicación «ng». En este caso el parámetro «new» indica que queremos crear un nuevo proyecto y a continuación el nombre del mismo.

ng new TicTacToe

Apunte. Error al ejecutar scripts en la consola:

ng : No se puede cargar el archivo C:\Users\Juan\AppData\Roaming\npm\ng.ps1 porque la ejecución de scripts está deshabilitada en este sistema. Para obtener más información, consulta el tema about_Execution_Policies

Esto se debe a una política de seguridad del sistema operativo que tendremos que modificar para poder ejecutar los scripts de angular. Se puede solucionar ejecutando el siguiente comando: «Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned«

Al ejecuar correctamente el comando, se creará el esqueleto «básico» de nuestra aplicación. Aunque no todo es necesario, es una plantilla estándar que usa Angular cuando creamos un nuevo proyecto. Antes de crearlo te preguntará si quieres añadir Angular routing y que tipo de formato de estilos querremos usar. Seleccionaremos no usar Angular Routing y formato de estilo CSS.

PS C:\Users\Juan\Desktop\AngularTests> ng new TicTacToe
? Would you like to share anonymous usage data about this project with the Angular Team at
Google under Google’s Privacy Policy at https://policies.google.com/privacy. For more
details and how to change this setting, see https://angular.io/analytics. No
Global setting: disabled
Local setting: No local workspace configuration file.
Effective status: disabled
? Would you like to add Angular routing? No
? Which stylesheet format would you like to use? CSS
CREATE TicTacToe/angular.json (2939 bytes)
CREATE TicTacToe/package.json (1042 bytes)
CREATE TicTacToe/README.md (1063 bytes)
CREATE TicTacToe/tsconfig.json (863 bytes)
CREATE TicTacToe/.editorconfig (274 bytes)
CREATE TicTacToe/.gitignore (548 bytes)
CREATE TicTacToe/.browserslistrc (600 bytes)
CREATE TicTacToe/karma.conf.js (1428 bytes)
CREATE TicTacToe/tsconfig.app.json (287 bytes)
CREATE TicTacToe/tsconfig.spec.json (333 bytes)
CREATE TicTacToe/.vscode/extensions.json (130 bytes)
CREATE TicTacToe/.vscode/launch.json (474 bytes)
CREATE TicTacToe/.vscode/tasks.json (938 bytes)
CREATE TicTacToe/src/favicon.ico (948 bytes)
CREATE TicTacToe/src/index.html (295 bytes)
CREATE TicTacToe/src/main.ts (372 bytes)
CREATE TicTacToe/src/polyfills.ts (2338 bytes)
CREATE TicTacToe/src/styles.css (80 bytes)
CREATE TicTacToe/src/test.ts (749 bytes)
CREATE TicTacToe/src/assets/.gitkeep (0 bytes)
CREATE TicTacToe/src/environments/environment.prod.ts (51 bytes)
CREATE TicTacToe/src/environments/environment.ts (658 bytes)
CREATE TicTacToe/src/app/app.module.ts (314 bytes)
CREATE TicTacToe/src/app/app.component.html (23332 bytes)
CREATE TicTacToe/src/app/app.component.spec.ts (965 bytes)
CREATE TicTacToe/src/app/app.component.ts (213 bytes)
CREATE TicTacToe/src/app/app.component.css (0 bytes)
√ Packages installed successfully.
"git" no se reconoce como un comando interno o externo,
programa o archivo por lotes ejecutable.

Con esto ya tendremos una carpeta con un proyecto listo para usar, con la inicialización por defecto de Angular. Lo podemos lanzar ejecutando el comando ng serve, desde dentro de la ruta del proyecto creado. El argumento -o nos abrirá en nuestro navegador por defecto la página cuando termine de compilar todo, en la dirección http://localhost:4200/

PS C:\Users\Juan\Desktop\AngularTests> cd .\TicTacToe\
PS C:\Users\Juan\Desktop\AngularTests\TicTacToe> ng serve -o
Pantalla por defecto de una aplicación angular recién creada

Codificación de nuestra aplicación

Vamos a distinguir los principales componentes que modificaremos en nuestra aplicación:

  • /src/app/app.component.html – Nuestra plantilla donde pintaremos el tablero de juego
  • /src/app/app.component.ts – Nuestro fichero Typescript que tendrá el controlador de nuestros componentes.

Para este ejemplo, modificamos el modulo «app» que nos crea angular por defecto. En un caso más real crearíamos estos módulos por cada una de las funcionalidades que queramos implementar en nuestra aplicación (autenticación, perfil…).

Nuestro fichero Html, vamos a crear la plantilla (o vista) que tendrá nuestra aplicación. La aplicación se compondrá de una barra inicial de título, dos inputs de texto que nos indicarán que jugador tiene el turno activo, un tablero con 9 casillas cuyo comportamiento variará al ser pulsados y un mensaje de juego finalizado cuando todas las casillas del tablero estén rellenas. (El juego no comprobará en ningún caso quien ganará, no es que no queramos complicar más las cosas, es que aquí no somos tan competitivos..)

En nuestro controlador typescript, modificaremos el modelo que formará la alicación, contando con: Título, una flag que indique si la partida ha finalizado, un contador de clicks (que nos servirá para controlar el cambio de turno), un array de 9 elementos que guardará la información del grid y 2 métodos, uno que nos dirán a que jugador pertenece cada turno y otro que nos permitirá cambiar el valor de un botón por el del jugador actual al ser pulsado y conocer si todas las casillas ya han sido cubiertas.

Nuestro fichero app.component.ts contendrá lo siguiente:

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'TicTacToe';

  gamecompleted = false;

  clicks = 0;
  grid  = [" "," "," "," "," "," "," "," "," "];

  isTurnPlayerX(){
    return this.clicks%2==0;
  }

  changeValueOfButton(position : number){
    if(this.grid[position] == " "){
      this.grid[position] = this.isTurnPlayerX()? "X" : "O";
      this.clicks++;
    }

    if(this.grid.filter(item => item == " ").length == 0){
      this.gamecompleted = true;
    }
  }
  
}

Nuestro fichero app.component.html contendrá el siguiente contenido:

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous" />
  </head>
  <body>
    <div class="container">
      <div class="container text-center bg-primary text-white">
        <h3>{{title}}</h3>
      </div>

      
      <div class="container" [ngSwitch]="gamecompleted">
        <div *ngSwitchCase="true" class="alert alert-primary text-center" role="alert">
          El juego ha finalizado
        </div>
      </div>

      <div class="container bg-light">
        <div class="row">
          <input type="text" class="col-6 p-2" [attr.disabled]="!isTurnPlayerX()?'disabled':null" value="PlayerX" />
          <input type="text" class="col-6 p-2" [attr.disabled]="isTurnPlayerX()?'disabled':null" value="PlayerO" />
        </div>
        <div class="row text-center">

          <button type="button" class="btn btn-warning col-3 m-4 p-5" 
            *ngFor="let gridItem of grid; let i = index"
            (click)="changeValueOfButton(i)">
            {{gridItem}}            
          </button>

        </div>
      </div>
    </div>



  </body>
</html>

Breve explicación del código

Inicialmente, al guardar estos cambios, nuestro navegador se habrá refrescado automáticamente y habrá aparecido esto:

Primer vistazo de nuestra nueva aplicación

Aquí vemos la estructura de la página (un poco personalizada usando bootstrap). Donde vemos que inicialmente está habilitado el campo de texto donde se indica PlayerX. Esto indica que el turno es del jugador que marca con X. Este comportamiento lo hacemos de la siguiente manera:

<input type="text" class="col-6 p-2" [attr.disabled]="!isTurnPlayerX()?'disabled':null" value="PlayerX" />
<input type="text" class="col-6 p-2" [attr.disabled]="isTurnPlayerX()?'disabled':null" value="PlayerO" />
isTurnPlayerX(){
  return this.clicks%2==0;
}

En base al resultado de nuestro método isTurnPlayerX, se añadirá o no el atributo disabled al elemento html donde se encuentra el nombre del usuario actual.

El tablero cuenta con un comportamiento personalizado. Al hacer click en cualquier casilla, escribimos el valor en nuestra tabla en la posición seleccionada. Aumentamos el contador de clicks para cambiar el turno y comprobamos si el juego ha terminado para mostrar o no la zona informativa.

changeValueOfButton(position : number){
    if(this.grid[position] == " "){
      this.grid[position] = this.isTurnPlayerX()? "X" : "O";
      this.clicks++;
    }

    if(this.grid.filter(item => item == " ").length == 0){
      this.gamecompleted = true;
    }
  }
<div class="container" [ngSwitch]="gamecompleted">
  <div *ngSwitchCase="true" class="alert alert-primary text-center" role="alert">
    El juego ha finalizado
  </div>
</div>
...
<button type="button" class="btn btn-warning col-3 m-4 p-5" 
            *ngFor="let gridItem of grid; let i = index"
            (click)="changeValueOfButton(i)">
            {{gridItem}}            
          </button>
...

Aquí podemos ver como se pintan ‘n’ elementos usando la directiva *ngFor de Angular (una por cada elemento de la propiedad grid del controlador). También asignamos un evento click que llamará a la función changeValueOfButton de nuestro controlador pasándole la posición por parámetro.

Tenemos una capa en la parte superior que muestra el valor «El juego ha finalizado» cuando la variable de nuestro controlador «gamecompleted» tiene el valor true. Para ello usamos la directiva ngSwitch, que hace la función de switcher de cualquier lenguaje de programación.

Conclusión

Mirando los dos ficheros podemos ir viendo el data-binding que se hacen entre vista y controlador. Cómo ya vimos, el propósito de este post era crear tu primera aplicación angular. Hemos establecido un primer contacto con Angular y hemos visto suficiente para poder personalizar más la aplicación si lo deseamos. Hay muchas opciones disponibles usando este framework, como añadir comportamientos más complejos al interactuar con un servidor REST, persistencia de datos, etc.. A partir de ahora se abre un nuevo camino donde investigar qué partido podemos sacar a Angular.

Crear tu primera aplicación con Angular
Etiquetado en:        

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Social media & sharing icons powered by UltimatelySocial