Tutorial: Aplicaciones de Angular CLI con bootstrap
Tags: angular, kikstart, beginners, espanol
Published: 2020-07-28 01:52:20

---
title: "Tutorial: Aplicaciones de Angular CLI con bootstrap"
description: "En este tutorial, tu aprendes cómo usar estilos en Apps de Angular CLI."
published: true
cover_image: ""
canonical_url: ""
tags: angular, kikstart, beginner, espanol
---

![Example of the pages of the final app](https://dev-to-uploads.s3.amazonaws.com/i/uisbw2k5xdupr3lrtipy.gif)

En este tutorial, tu aprendes cómo usar estilos en Apps de Angular CLI.

La meta es construir un layout en una aplicación con un header y un footer, una página home, página about y una página login con formulario.

Mira el [demo en vivo aquí](https://tutorial-styling-angular-cli-apps-with-bootstrap.netlify.app/home) o el [repositorio de Github](https://github.com/beeman/tutorial-styling-angular-cli-apps-with-bootstrap).

## Requisitos

Asegurate que tienes la siguientes herramientas instaladas:

- Node.js y NPM, visita su [pagina web](https://nodejs.org/en/) para las instrucciones de instalación.
  - Ejecuta `node -v` para verificar que tienes versión 12 o más.
  - Ejecuta `npm -v` para verificar que tienes la versión 6 o más.
- Angular CLI ( `npm install -g @angular/cli@latest`  para instalar).
  - Ejecuta `ng --version`  para verificar que tienes versión 10 o más.

Si prefieres usar `yarn`, primero [configura el package manager de Angular CLI ](https://beeman.dev/posts/using-yarn-with-angular-cli-1n73/). Esto asegura que la aplicación esta creado con un archivo `yarn.lock` en vez de un `package-lock.json`.

## 1. Crea una nueva aplicación 

Abre un terminal y ejecuta el siguiente comando:

```bash
ng new sandbox --routing --style scss --strict
```

El comando  `ng new` genera una aplicación Angular básica en un directorio llamado `sandbox` e instala sus dependencias.

El  `--routing`  le indica a Angular CLI  que se genere un módulo de rutas.
El `--style scss` indica que usamos SCSS para los estilos.
El `--strict` configura la aplicación para ejecutarse en [modo estricto](https://angular.io/guide/strict-mode).

Al final de la instalación del app, el Angular CLI también inicializa un repositorio de git y hace un commit inicial.

## 2. Inicia la aplicación en modo de desarrollo

Después de haber finalizado la instalación, ejecuta el siguiente comando para navegar al `directorio del proyecto`.

```bash
cd sandbox
```

En el directorio del proyecto, puedes iniciar el servidor de desarrollo usando `ng serve`:

```bash
ng serve
```

> ** Angular Live Development Server is listening on localhost:4200, open your browser on (http://localhost:4200/) **

Navega al link mencionado antes por el servidor de desarrollo  y verifica que esté funcionando. El app está lista para tener algunos estilos!  😎

## 3. Instala Bootstrap

Ejecuta el siguiente comando en el directorio de tu proyecto para instalar Bootstrap:

```bash
npm install bootstrap
```

Cuando la instalación finaliza podemos decirle a Angular CLI que use estos estilos.

Abre `src/styles.scss` y agrega las siguientes líneas:

```scss
@import '~bootstrap/scss/bootstrap';
// Set the full page height so we can stick the footer to the bottom
html,
body {
  height: 100%;
}
```

Después abre `src/app/app.component.html` y borra todo el contenido,reemplazalo con lo siguiente:

```html
<h1 class="text-center text-primary">Hello Bootstrap!</h1>
```

Cuando regreses a tu navegador, deberías ver `Hello Bootstrap` en letras azules grandes 👏🎊.

¡Podemos hacer que nuestra aplicación se vea mejor!

## 4. Configura el layout de la aplicación

![The basic application layout](https://dev-to-uploads.s3.amazonaws.com/i/890nao89aq581a8xiles.png)

En este paso creamos un `UiModule` y le agregamos 3 componentes:

` LayoutComponent`, `HeaderComponent`, y `FooterComponent`.

> 💡Es una buena idea mantener el UI separado del resto de la app. Esta separación de responsabilidades también te  permite fácilmente reutilizar el UI en otros proyectos.

## 4.1 Crea el UiModule

Ejecuta el siguiente comando para generar el `UiModule`.

```bash
ng generate module ui --module app
```

Despues, genera los 3 componentes dentro de este nuevo módulo:

```bash
ng generate component ui/layout
ng generate component ui/header
ng generate component ui/footer
```

> 💡 El comando `ng generate` admite un acceso directo: Usa `ng g c` para generar un componente, `ng g m` para generar un módulo, etc.

## 4.2 Implementa Layout Component

Abre `src/app/ui/layout/layout.component.html` y reemplaza el contenido con el siguiente pedazo de código:

```html
<!-- This flex container takes the full height -->
<div class="d-flex flex-column h-100">
  <app-header></app-header>
  <!-- The main area does not shrink, 'pushing down' the footer -->
  <main class="flex-shrink-0">
    <!-- This will render the routes -->
    <router-outlet></router-outlet>
  </main>
  <!-- This keeps the footer down if the main content does not fill up the space -->
  <footer class="mt-auto">
    <app-footer></app-footer>
  </footer>
</div>
```

Podemos usar este `LayoutComponent` en la ruta, y renderizar los `children` en la ubicación de `router-outlet`. 

Antes de seguir, asegurate de importar `RouterModule` en `UiModule`.

Abre `src/app/ui/ui.module.ts` y agrega el siguiente código después de los otros imports:

```typescript
import { RouterModule } from '@angular/router';
```

Agrega `RouterModule` a el array de imports:

```typescript
@NgModule({
  declarations: [LayoutComponent, HeaderComponent, FooterComponent],
  imports: [CommonModule, RouterModule],
})
```

> 💡Si olvidas el import de `RouterModule`, el servidor te dira:

    ERROR in src/app/ui/layout/layout.component.html:3:3 - error NG8001: 'router-outlet' is not a known element:
      1.  If 'router-outlet' is an Angular component, then verify that it is part of this module.
      2.  If 'router-outlet' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.</pre>

## 4.3 Usa el LayoutComponent

Abre `src/app/app-routing.module.ts` y reemplaza la linea `const routes: Routes = []` con lo siguiente:

```typescript
const routes: Routes = [
  {
    path: '',
    component: LayoutComponent,
    children: [
      // Here we will add our application pages
    ],
  },
];
```

Asegurate de importar `LayoutComponent` en `src/app/app-routing.module.ts`:

```typescript
import { LayoutComponent } from './ui/layout/layout.component';
```

Abre `src/app/app.component.html` y reemplaza el contenido con la siguiente línea: 

```html
<router-outlet></router-outlet>
```

Guarda todos los archivos y revisa en tu navegador, deberías ver el  `HeaderComponent` y `FooterComponent` renderizados. Hora de decorarlas!

## 4.4 Implementa el Header

Abre `src/app/ui/header/header.component.html` y reemplaza el contenido con lo siguiente:

```html
<!-- You can change the values `dark` here with any of the following: -->
<!-- dark, light, primary, secondary, success, info, danger, warning -->
<nav class="navbar navbar-dark bg-dark">
  <!-- This is the application title with a link to the root -->
  <a class="navbar-brand" routerLinkActive="active" routerLink="/">Angular & Bootstrap</a>
  <!-- This is a spacer so the links move to the end -->
  <div class="mr-auto"></div>
  <!-- This main navigation links are defined here -->
  <div class="navbar-expand">
    <div class="navbar-nav">
      <!-- Each link has the routerLink property set to a different route -->
      <a class="nav-item nav-link" routerLinkActive="active" routerLink="/home">Home</a>
      <a class="nav-item nav-link" routerLinkActive="active" routerLink="/about">About</a>
      <a class="nav-item nav-link" routerLinkActive="active" routerLink="/login">Login</a>
    </div>
  </div>
</nav>
```

Refiere a la [documentación de navbar en bootstrap] (https://getbootstrap.com/docs/4.5/components/navbar/) para mas detalles de la sintaxis del navbar y como hacerlos responsivo.

## 4.5 Implementa el Footer

Abre `src/app/ui/footer/footer.component.html` y reemplaza el contenido con esto:

```html
<div class="py-3 bg-dark text-center text-muted">
  <small>Copyright &copy; 2020</small>
</div>
```

## 5. Agregar páginas de aplicación

Cuando el layout de la aplicación esté en su lugar, es el momento de agregar unas páginas.

El comando que usamos crea un módulo con un componente y usa [lazy-loading](https://angular.io/guide/lazy-loading-ngmodules) para registrarlo en el `AppModule`.

> 💡Lazy loading es recomendado como una manera de enrutar en una app de Angular, ya que se asegura que los usuarios no descarguen código que no se usará.

## 5.1 Crea una pagina Home

Ejecuta el siguiente comando para generar el `HomeModule`:

```bash
ng g module pages/home --route home --module app
```

Abre `src/app/pages/home/home.component.html` y reemplaza el contenido con esto:

```html
<div class="container py-5">
  <div class="jumbotron">
    <h1 class="text-secondary">Home</h1>
  </div>
</div>
```

Ve a la aplicación en el navegador y haz clic en el enlace `Home` en el header.

Te llevará a la ruta `/home` con el texto 'Home'. Sin embargo, el layout con el header y el footer se ha ido!

Para arreglar esto, abre `src/app/app-routing.module.ts` y mueve la ruta creada recientemente dentro del array `children`.

 ```typescript
const routes: Routes = [
  {
    path: '',
    component: LayoutComponent,
    children: [
      // Here we will add our application pages
      {
        path: 'home',
        loadChildren: () => import('./pages/home/home.module').then(m => m.HomeModule),
      },
    ],
  },
];
 ```

Después de guardar este archivo, la pagina deberia renderizarse apropiadamente.

## 5.2  Crea la pagina About

Ejecuta el siguiente comando para generar el `AboutComponent`:

```bash
ng g module pages/about --route about --module app
```

Abre `src/app/pages/about/about.component.html` y reemplaza el contenido con esto:

```html
<div class="container py-5">
  <div class="jumbotron">
    <h1 class="text-secondary">About</h1>
  </div>
</div>
```

Abre `src/app/app-routing.module.ts` y mueve la ruta de about dentro del array `children` para que se encuentre al lado de la ruta de `HomeModule`.

## 5.3 Crea la pagina Login 

La página de login es un poco más compleja porque tiene un formulario y usa el router para redirigir el usuario.

Ejecuta el siguiente comando para generar el `LoginModule`:

```bash
ng g module pages/login --route login --module app
```

Abre `src/app/pages/login/login.component.ts` y agrega el siguiente codigo despues de los otros imports:

```typescript
import { FormControl, FormGroup } from '@angular/forms';
import { Router } from '@angular/router';
```

Cambia el contenido del cuerpo de la clase `LoginComponent` con esto:

```typescript
export class LoginComponent implements OnInit {
  // The form group defines the fields used in the form
  form = new FormGroup({
    email: new FormControl(''),
    password: new FormControl(''),
  });

  // Inject the router so we can navigate after a successful login
  constructor(private readonly router: Router) {}

  ngOnInit(): void {}

  public submit() {
    // Use the form value to do authentication
    console.log(this.form.value);
    // Navigate after successful login
    return this.router.navigate(['/']);
  }
}
```

Abre `src/app/pages/login/login.component.html` y reemplaza el contenido con lo siguiente:

```html
<!-- This flex container takes the full height and vertically centers the content -->
<div class="d-flex flex-column h-100 justify-content-center">
  <div class="container">
    <div class="row">
      <!-- This is a single column that is responsive -->
      <div class="col-12 col-md-6 offset-md-3">
        <div class="card">
          <div class="card-header">Login</div>
          <div class="card-body">
            <!-- The formGroup 'form' is defined in the component class -->
            <form [formGroup]="form">
              <div class="form-group">
                <label for="email">Email address</label>
                <!-- The formControlName defines the name of the field in the formGroup -->
                <input id="email" formControlName="email" type="email" required class="form-control" />
              </div>
              <div class="form-group">
                <label for="password">Password</label>
                <input id="password" formControlName="password" type="password" required class="form-control" />
              </div>
            </form>
          </div>
          <div class="card-footer">
            <div class="d-flex justify-content-between">
              <a routerLink="/" class="ml-2 btn btn-outline-secondary">
                Home
              </a>
              <!-- The button has a click handler, it will be disabled if the form is not valid -->
              <button (click)="submit()" [disabled]="!form.valid" type="submit" class="btn btn-outline-success">
                Log in
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
```

> 💡 El template del `LoginComponent` es bastante largo. Cuando agregues más páginas de autenticación, considera crear un `AuthLayoutComponent` separado y  usalo como `LayoutComponent`, luego agrega `LoginComponent`, `RegisterComponent` etc, como elementos secundarios de  `AuthLayoutComponent`.

Ve a tu aplicación en el navegador y da clic al enlace `Login` en el header.

La página de login renderiza el formulario en el centro de la pantalla y no necesitamos agregar la ruta en el array de `children`.

Hay una última cosa por arreglar. Si haces clic en el enlace `Home`, volverá a la raíz de la aplicación que está en blanco.

¿ No sería genial si pudiéramos ir a la página de inicio 😱?

## 5.4  Redirigir la ruta inicial 

Abre `src/app/app-routing.module.ts` y agregar el siguiente objeto en la parte superior del array de rutas:

```typescript
const routes: Routes = [
  {
    path: '',
    // If this path is the 'full' match...
    pathMatch: 'full',
    // ...redirect to this route.
    redirectTo: 'home',
  },
  // The other routes go here
];
```

## ¿A dónde ir desde aquí?

Como se indicó en la introducción, esta aplicación es un punto de partida y debería ser bastante sencilla para mejorarla a tu gusto.

### Librerías adicionales

Usa [ng-bootstrap](https://ng-bootstrap.github.io/#/home) o [ngx-bootstrap](https://valor-software.com/ngx-bootstrap/#/) si deseas usar implementaciones de los componentes de bootstrap, como menús desplegables, pestañas, colapsar, etc. Ambas librerías son excelentes opciones, elija la que más le guste.

Si tus aplicaciones tienen muchos formularios, usa [formly](https://formly.dev/) para una forma declarativa de definir sus formularios, sin escribir ninguna de las plantillas de formulario.

### Temas y colores

Para ajustar la apariencia de Bootstrap, abre `src/styles.scss` y configura las variables. Asegúrate de definir las variables antes de importar Bootstrap:

```bash
$dark: hotpink;
$jumbotron-bg: #333;
$secondary: limegreen;
$body-bg: #555;
@import '~bootstrap/scss/bootstrap';
```

Otra opción genial es [Bootswatch](https://bootswatch.com/), que ofrece más de 20 diseños diferentes basados en bootstrap.

## Conclusión

En este tutorial, tu aprendiste cómo crear una aplicación básica de Angular y usaste bootstrap para crear un layout con header y footer.

La app tiene varias páginas que son `lazy loaded`. La página de login tiene un formulario con validación básica y un redireccionamiento a la página de Home.

En caso que tengas alguna pregunta, siéntete libre para comentar en DEV o enviame un mensaje a mi [twitter](https://twitter.com/derlys_paola)!

Muchas gracias por leerme y hagan mucho código 🤓