El valor de un hombre debe medirse por lo que da y no por lo que recibe. No trates de convertirte en un hombre de éxito sino en un hombre de valores - Albert Einstein
Implementa el servicio Angular Router, que permite la navegación de una vista a la siguiente a medida que los usuarios realizan tareas de la aplicación.
CREACIÓN, INSTALACIÓN Y PUESTA EN MARCHA DE NUESTRO ESPACIO DE TRABAJO Y APLICACIÓN ANGULAR
- Verificando la existencia de nuestra herramienta de comandos Angular CLI mediante el comando
ng
- Versión de nuestro de nuestra herramienta de comandos Angular CLI ejecutando el comando
ng version
- Solicitando ayuda a nuestra herramienta de comandos Angular CLI haciendo uso del comando
ng help
- Obtener información detallada de como crear nuestro espacio de trabajo para la aplicación mediante la herramienta de comandos Angular CLI con el comando
ng new --help
- Creando nuestro espacio de trabajo para la aplicación ejecutando el comando
ng new router-fast-and-guards
haciendo uso de la herramienta de comandos Angular CLI- ? Do you want to enforce stricter type checking and stricter bundle budgets in the workspace? This setting helps improve maintainability and catch bugs ahead of time. For more information, see https://angular.io/strict (y/N) N
- ? Would you like to add Angular routing? (y/N) y
- ? Which stylesheet format would you like to use? CSS
- 😴 ¡Calma¡ NO desesperemos falta poco
- Ingresar al espacio de trabajo creado mediante el comando
cd router-fast-and-guards
- Corriendo nuestra aplicación sobre el entorno de desarrollo lanzando el comando
ng serve
haciendo uso de la herramienta de comandos Angular CLI- ? 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 http://angular.io/analytics. (y/N) N
- 😴 ¡Calma¡ NO desesperemos falta poco
- ✔ Compiled successfully abriremos una prestaña de nuestro navegador web e ingresaremos a la dirección
http://localhost:4200
!Lo hemos conseguido ya tenemos nuestra aplicación en modo 🚀¡
Sugerencias:
- Obtener información detallada de como crear y correr nuestra aplicación mediante la herramienta de comandos Angular CLI ejecuanto el comando
ng serve --help
- Corriendo nuestra aplicación y abriendo el enlace a nuestro aplicación sobre una pestaña del navegador web predeterminado de nuestro sistema operativo sobre el entorno de desarrollo lanzando el comando
ng serve --open
haciendo uso de la herramienta de comandos Angular CLI
- Creación de módulo con nombre user-profile haciendo uso de la herramienta de comandos Angular CLI mediante el comando
ng generate module /modules/user-profile --module=app --route=user-profile --routing --routing-scope=Child
- Ingresamos a la dirección
http://localhost:4200/user-profile
sobre nuestra navegador web para ver el módulo user-profile
- Ingresamos a la dirección
- Creación de módulo con nombre distinctive haciendo uso de la herramienta de comandos Angular CLI mediante el comando
ng generate module /modules/distinctive --module=app --route=distinctive --routing --routing-scope=Child
- Ingresamos a la dirección
http://localhost:4200/distinctive
sobre nuestra navegador web para ver el módulo distinctive
- Ingresamos a la dirección
- Creación de módulo con nombre groups haciendo uso de la herramienta de comandos Angular CLI mediante el comando
ng generate module /modules/groups --module=app --route=groups --routing --routing-scope=Child
- Ingresamos a la dirección
http://localhost:4200/groups
sobre nuestra navegador web para ver el módulo groups - Creación de submódulo con nombre angular haciendo uso de la herramienta de comandos Angular CLI mediante el comando
ng generate module /modules/groups/submodules/angular --module=/modules/groups --route=angular --routing --routing-scope=Child
- Ingresamos a la dirección
http://localhost:4200/groups/angular
sobre nuestra navegador web para ver el submódulo angular
- Ingresamos a la dirección
- Creación de submódulo con nombre react haciendo uso de la herramienta de comandos Angular CLI mediante el comando
ng generate module /modules/groups/submodules/react --module=/modules/groups --route=react --routing --routing-scope=Child
- Ingresamos a la dirección
http://localhost:4200/groups/react
sobre nuestra navegador web para ver el submódulo react
- Ingresamos a la dirección
- Creación de submódulo con nombre vue haciendo uso de la herramienta de comandos Angular CLI mediante el comando
ng generate module /modules/groups/submodules/vue --module=/modules/groups --route=vue --routing --routing-scope=Child
- Ingresamos a la dirección
http://localhost:4200/groups/vue
sobre nuestra navegador web para ver el submódulo vue
- Ingresamos a la dirección
- Creación de submódulo con nombre svelte haciendo uso de la herramienta de comandos Angular CLI mediante el comando
ng generate module /modules/groups/submodules/svelte --module=/modules/groups --route=svelte --routing --routing-scope=Child
- Ingresamos a la dirección
http://localhost:4200/groups/svelte
sobre nuestra navegador web para ver el submódulo svelte
- Ingresamos a la dirección
- Convirtiendo submódulos angular, react, vue, svelte en rutas hijas de groups
- Integración de etiqueta
<router-outlet></router-outlet>
sobre fichero HTMLsrc/app/modules/groups/groups.component.html
- Moviendo rutas de "submódulos" del "módulo" groups sobre fichero de rutas
src/app/modules/groups/groups-routing.module.ts
haciendo uso de la propiedad children de la ruta padre declarada
const routes: Routes = [{ path: '', component: GroupsComponent, children: [{ path: 'angular', loadChildren: () => import('./submodules/angular/angular.module').then(m => m.AngularModule) }, { path: 'react', loadChildren: () => import('./submodules/react/react.module').then(m => m.ReactModule) }, { path: 'vue', loadChildren: () => import('./submodules/vue/vue.module').then(m => m.VueModule) }, { path: 'svelte', loadChildren: () => import('./submodules/svelte/svelte.module').then(m => m.SvelteModule) }] }];
- Navegando "submódulos" del "módulo" groups
- Ingresamos a la dirección
http://localhost:4200/groups/angular
sobre nuestra navegador web para ver el submódulo angular - Ingresamos a la dirección
http://localhost:4200/groups/react
sobre nuestra navegador web para ver el submódulo react - Ingresamos a la dirección
http://localhost:4200/groups/vue
sobre nuestra navegador web para ver el submódulo vue - Ingresamos a la dirección
http://localhost:4200/groups/svelte
sobre nuestra navegador web para ver el submódulo svelte
- Ingresamos a la dirección
- Integración de etiqueta
- Ingresamos a la dirección
- Creación de módulo events haciendo uso de la herramienta de comandos Angular CLI mediante el comando
ng generate module /modules/events --module=app --route=events --routing --routing-scope=Child
- Ingresamos a la dirección
http://localhost:4200/events
sobre nuestra navegador web para ver el módulo events
- Ingresamos a la dirección
- Implementación de enlaces para navegar por los diferentes módulos padres user-profile, distinctive, groups, events sobre fichero HTML
src/app/app.component.html
haciendo uso de la directiva routerLink y directiva routerLinkActive encargada de agregar una clase al enlace activo.
.card-container .card:not(.highlight-card):hover, .card-container .card.active {
transform: translateY(-3px);
box-shadow: 0 4px 17px rgba(0, 0, 0, 0.35);
}
<div class="card-container">
<a class="card card-small" routerLink="/user-profile" routerLinkActive="active">
<span>User profile</span>
</a>
<a class="card card-small" routerLink="/distinctive" routerLinkActive="active">
<span>Distinctive</span>
</a>
<a class="card card-small" routerLink="/groups" routerLinkActive="active">
<span>Groups</span>
</a>
<a class="card card-small" routerLink="/events" routerLinkActive="active">
<span>Events</span>
</a>
</div>
- Implementación de enlaces para navegar por los diferentes submódulos hijos angular, react, vue, svelt del módulo padre groups sobre fichero HTML
src/app/modules/groups/groups.component.html
haciendo uso de la directiva routerLink y directiva routerLinkActive encargada de agregar una clase al enlace activo.
<style>
:host {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
font-size: 14px;
color: #333;
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
h1,
h2,
h3,
h4,
h5,
h6 {
margin: 8px 0;
}
p {
margin: 0;
}
.spacer {
flex: 1;
}
.toolbar {
position: absolute;
top: 0;
left: 0;
right: 0;
height: 60px;
display: flex;
align-items: center;
background-color: #1976d2;
color: white;
font-weight: 600;
}
.toolbar img {
margin: 0 16px;
}
.toolbar #twitter-logo {
height: 40px;
margin: 0 16px;
}
.toolbar #twitter-logo:hover {
opacity: 0.8;
}
.content {
display: flex;
margin: 82px auto 32px;
padding: 0 16px;
max-width: 960px;
flex-direction: column;
align-items: center;
}
svg.material-icons {
height: 24px;
width: auto;
}
svg.material-icons:not(:last-child) {
margin-right: 8px;
}
.card svg.material-icons path {
fill: #888;
}
.card-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
margin-top: 16px;
}
.card {
border-radius: 4px;
border: 1px solid #eee;
background-color: #fafafa;
height: 40px;
width: 200px;
margin: 0 8px 16px;
padding: 16px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
transition: all 0.2s ease-in-out;
line-height: 24px;
}
.card-container .card:not(:last-child) {
margin-right: 0;
}
.card.card-small {
height: 16px;
width: 168px;
}
.card-container .card:not(.highlight-card) {
cursor: pointer;
}
.card-container .card:not(.highlight-card):hover, .card-container .card.active {
transform: translateY(-3px);
box-shadow: 0 4px 17px rgba(0, 0, 0, 0.35);
}
.card-container .card:not(.highlight-card):hover .material-icons path {
fill: rgb(105, 103, 103);
}
.card.highlight-card {
background-color: #1976d2;
color: white;
font-weight: 600;
border: none;
width: auto;
min-width: 30%;
position: relative;
}
.card.card.highlight-card span {
margin-left: 60px;
}
svg#rocket {
width: 80px;
position: absolute;
left: -10px;
top: -24px;
}
svg#rocket-smoke {
height: calc(100vh - 95px);
position: absolute;
top: 10px;
right: 180px;
z-index: -10;
}
a,
a:visited,
a:hover {
color: #1976d2;
text-decoration: none;
}
a:hover {
color: #125699;
}
.terminal {
position: relative;
width: 80%;
max-width: 600px;
border-radius: 6px;
padding-top: 45px;
margin-top: 8px;
overflow: hidden;
background-color: rgb(15, 15, 16);
}
.terminal::before {
content: "\2022 \2022 \2022";
position: absolute;
top: 0;
left: 0;
height: 4px;
background: rgb(58, 58, 58);
color: #c2c3c4;
width: 100%;
font-size: 2rem;
line-height: 0;
padding: 14px 0;
text-indent: 4px;
}
.terminal pre {
font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
color: white;
padding: 0 1rem 1rem;
margin: 0;
}
.circle-link {
height: 40px;
width: 40px;
border-radius: 40px;
margin: 8px;
background-color: white;
border: 1px solid #eeeeee;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
transition: 1s ease-out;
}
.circle-link:hover {
transform: translateY(-0.25rem);
box-shadow: 0px 3px 15px rgba(0, 0, 0, 0.2);
}
footer {
margin-top: 8px;
display: flex;
align-items: center;
line-height: 20px;
}
footer a {
display: flex;
align-items: center;
}
.github-star-badge {
color: #24292e;
display: flex;
align-items: center;
font-size: 12px;
padding: 3px 10px;
border: 1px solid rgba(27, 31, 35, .2);
border-radius: 3px;
background-image: linear-gradient(-180deg, #fafbfc, #eff3f6 90%);
margin-left: 4px;
font-weight: 600;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
}
.github-star-badge:hover {
background-image: linear-gradient(-180deg, #f0f3f6, #e6ebf1 90%);
border-color: rgba(27, 31, 35, .35);
background-position: -.5em;
}
.github-star-badge .material-icons {
height: 16px;
width: 16px;
margin-right: 4px;
}
svg#clouds {
position: fixed;
bottom: -160px;
left: -230px;
z-index: -10;
width: 1920px;
}
/* Responsive Styles */
@media screen and (max-width: 767px) {
.card-container>*:not(.circle-link),
.terminal {
width: 100%;
}
.card:not(.highlight-card) {
height: 16px;
margin: 8px 0;
}
.card.highlight-card span {
margin-left: 72px;
}
svg#rocket-smoke {
right: 120px;
transform: rotate(-5deg);
}
}
@media screen and (max-width: 575px) {
svg#rocket-smoke {
display: none;
visibility: hidden;
}
}
</style>
<div class="card-container">
<a class="card card-small" routerLink="/groups/angular" routerLinkActive="active">
<span>Angular</span>
</a>
<a class="card card-small" routerLink="/groups/react" routerLinkActive="active">
<span>React</span>
</a>
<a class="card card-small" routerLink="/groups/vue" routerLinkActive="active">
<span>Vue</span>
</a>
<a class="card card-small" routerLink="/groups/svelte" routerLinkActive="active">
<span>Svelte</span>
</a>
</div>
Aplicando Lazy Loading en Angular Precargando módulos en Angular Usando Quicklink para precargar contenido en sitios web
Angular Router Angular Router In Depth
Prevenir el acceso NO AUTORIZADO
Protectores de ruta para evitar que los usuarios naveguen a partes de una aplicación sin autorización. Los siguientes protectores de ruta están disponibles en Angular:
- CanActivate decide si se puede activar una ruta.
- Creación de guardia con nombre can-activate haciendo uso de la herramienta de comandos Angular CLI mediante el comando
ng generate guard /guards/canActivate --implements=CanActivate --project=app.module
- Importar guardia sobre los proveedores del módulo
src/app/app.module.ts
- Creación de guardia con nombre can-activate haciendo uso de la herramienta de comandos Angular CLI mediante el comando
- CanActivateChild decide si se puede activar una ruta secundaria/hija.
- Creación de guardia con nombre can-activate-child haciendo uso de la herramienta de comandos Angular CLI mediante el comando
ng generate guard /guards/canActivateChild --implements=CanActivateChild
- Importar guardia sobre los proveedores del módulo
src/app/app.module.ts
- Creación de guardia con nombre can-activate-child haciendo uso de la herramienta de comandos Angular CLI mediante el comando
- CanDeactivate decide si una ruta puede desactivarse.
- Creación de guardia con nombre can-deactivate haciendo uso de la herramienta de comandos Angular CLI mediante el comando
ng generate guard /guards/canDeactivate --implements=CanDeactivate
- Importar guardia sobre los proveedores del módulo
src/app/app.module.ts
- Creación de guardia con nombre can-deactivate haciendo uso de la herramienta de comandos Angular CLI mediante el comando
- Resolve resuelve datos durante la navegación.
- Creación de guardia con nombre resolve haciendo uso de la herramienta de comandos Angular CLI mediante el comando
ng generate resolver /guards/resolve
- Importar guardia sobre los proveedores del módulo
src/app/app.module.ts
- Creación de guardia con nombre resolve haciendo uso de la herramienta de comandos Angular CLI mediante el comando
- CanLoad decide si se pueden cargar la ruta secundaria/hija mediante carga perezosa.
- Creación de guardia con nombre can-load haciendo uso de la herramienta de comandos Angular CLI mediante el comando
ng generate guard /guards/canLoad --implements=CanLoad
- Importar guardia sobre los proveedores del módulo
src/app/modules/groups/groups.module.ts
- Creación de guardia con nombre can-load haciendo uso de la herramienta de comandos Angular CLI mediante el comando
// src/app/app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { CanActivateChildGuard } from './guards/can-activate-child.guard';
import { CanActivateGuard } from './guards/can-activate.guard';
import { CanDeactivateGuard } from './guards/can-deactivate.guard';
import { CanLoadGuard } from './guards/can-load.guard';
import { ResolveResolver } from './guards/resolve.resolver';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
],
providers: [
CanActivateGuard,
CanActivateChildGuard,
CanDeactivateGuard,
ResolveResolver,
CanLoadGuard
],
bootstrap: [AppComponent]
})
export class AppModule { }
// src/app/app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CanActivateChildGuard } from './guards/can-activate-child.guard';
import { CanActivateGuard } from './guards/can-activate.guard';
import { CanDeactivateGuard } from './guards/can-deactivate.guard';
import { ResolveResolver } from './guards/resolve.resolver';
const routes: Routes = [{
path: 'user-profile',
loadChildren: () => import('./modules/user-profile/user-profile.module').then(m => m.UserProfileModule),
canActivate: [CanActivateGuard]
}, {
path: 'distinctive',
loadChildren: () => import('./modules/distinctive/distinctive.module').then(m => m.DistinctiveModule),
canDeactivate: [CanDeactivateGuard]
}, {
path: 'groups',
loadChildren: () => import('./modules/groups/groups.module').then(m => m.GroupsModule),
canActivateChild: [CanActivateChildGuard]
}, {
path: 'events',
loadChildren: () => import('./modules/events/events.module').then(m => m.EventsModule),
resolve: [ResolveResolver]
}];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
// src/app/modules/groups/groups-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CanLoadGuard } from 'src/app/guards/can-load.guard';
import { GroupsComponent } from './groups.component';
const routes: Routes = [{
path: '', component: GroupsComponent,
canLoad: [CanLoadGuard],
children: [{
path: 'angular',
loadChildren: () => import('./submodules/angular/angular.module').then(m => m.AngularModule)
}, {
path: 'react',
loadChildren: () => import('./submodules/react/react.module').then(m => m.ReactModule)
}, {
path: 'vue',
loadChildren: () => import('./submodules/vue/vue.module').then(m => m.VueModule)
}, {
path: 'svelte',
loadChildren: () => import('./submodules/svelte/svelte.module').then(m => m.SvelteModule)
}]
}];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class GroupsRoutingModule { }