Conjunto de herramientas, librerías y/o técnicas que nos permiten resolver un problema de una manera más elegante, sencilla y que nos permitirá resolver problemas nuevos similares de la misma manera.
Muchos frameworks nos proporcionan una estructura del proyecto ha seguir y siempre la misma, muchos framworks nos facilitan resolver problemas comunes de manera sencilla (digamos que, como jquery lo hacía con la manipulación del dom) etc etc
Tanto, que ya no se le llaman webs, y nace el concepto de
WEBAPPS
FACEBOOK, WHATSAPP WEB, SPOTIFY, APLICACIONES MÓVILES HÍBRIDAS, APLICACIONES DE ESCRITORIO CON ELECTRON
Cada vez más:
AJAX
webapps
index.html
<div>
</div>
Ordenador usuario
Servidor facebook
== DAME EL index.HTML =>
<= Toma el index.html ==
== El usuario navega a categories.html =>
Se refresca la pantalla
== NAVEGO a categorias.html =>
<= Toma el categorias.html ==
Se refresca la pantalla
Dame todos los ficheros
Toma los scripts y los css
Dame todos los ficheros
Toma los scripts y los css
Ordenador usuario
Servidor facebook
== DAME EL index.HTML =>
<= Toma el index.html ==
== El usuario navega a categories.html =>
Se refresca la pantalla
NAVEGO a categorias.html
Me autosirvo el template
Me renderizo una cosa nueva
Dame todos los ficheros
Toma los scripts y los css
ng new project
npm install -g @angular/cli
ng new project
ng new project
Esto es lo importante
Nos encontraremos que cada página o componente se compone de :
un fichero .html
un fichero .css
un fichero .ts
LA VISTA
EL MAQUILLAJE
LA LOGICA
¿Cómo arrancamos nuestro proyecto?
ng serve
Localhost:4200
EL INDEX ESTÁ VACIOO ??
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Angular - Example</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
Que vemos en localhost:4200
En el html
Mientras tanto ... en la web
Que vemos en localhost:4200
En el html
Mientras tanto ... en la web
Escribamos esto en el .html
En /src/app/app.component.html
Mientras tanto ... en la web
<h1>Hola mi nombre es {{name}}</h1>
<input [(ngModel)]="name">
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent
name = 'Yunior';
}
En /src/app/app.component.ts
Escribamos esto en el .html
En /src/app/app.component.html
Mientras tanto ... en la web
<h1>Hola mi nombre es {{name}}</h1>
<input [(ngModel)]="name">
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent
name = 'Yunior';
}
En /src/app/app.component.ts
Todo eso de ahí se nos escribirá siempre solo, automáticamente
¿cómo harías esto en JS vanilla?
¿cómo harías esto en JS vanilla?
Paso 1
<input id="elInput" type="text">
¿cómo harías esto en JS vanilla?
Paso 1
<input id="elInput" type="text">
Paso 2
const selectElement = document.getElementById('elInput');
selectElement.addEventListener('change', (event) => {
console.log(`The value is here => ${event.target.value} `)
});
¿cómo harías esto en JS vanilla?
Paso 1
<input id="elInput" type="text">
Paso 2
const selectElement = document.getElementById('elInput');
selectElement.addEventListener('change', (event) => {
console.log(`The value is here => ${event.target.value} `)
});
Paso 3
<h2> Hola mi nombre es <span id="resultado"></span></h2>
¿cómo harías esto en JS vanilla?
Paso 1
<input id="elInput" type="text">
Paso 2
const selectElement = document.getElementById('elInput');
selectElement.addEventListener('change', (event) => {
console.log(`The value is here => ${event.target.value} `)
});
Paso 3
<h2> Hola mi nombre es <span id="resultado"></span></h2>
Paso 4
const selectElement = document.getElementById('elInput');
selectElement.addEventListener('change', (event) => {
const resultado = document.getElementById('resultado');
resultado.innerText = event.target.value;
});
¿Los profes de JS .. nos sabemos todo esto de memoria?
Ahora ... con angular o cualquier framework
<h1>Hola mi nombre es {{nombre}}</h1>
<input [(ngModel)]="nombre">
2 ways data binding
TypeScript is a typed superset of JavaScript
that compiles to plain JavaScript
A superset
Error
function createUser(email, name, age){ ...}
Javascript
function createUser(email: string, name: string, age: number){ ...
}
Typescript
//Se declara de la siguiente forma.
export class AppComponent {
public name: string = 'Manolín';
constructor () {
//El constructor es el que primero se
//inicializa al iniciar la clase.
alert(`${this.getHello()} ${this.name}`)
}
// Para declarar una función
public getHello() : string {
return 'Hello';
}
}
this this this
this this this
this this this
this this this
this this this
TWO WAYS DATA BINDING
Nos encontraremos que cada página o componente se compone de :
un fichero .html
un fichero .css
un fichero .ts
Nos encontraremos que cada página o componente se compone de :
un fichero .html
un fichero .css
un fichero .ts
LA VISTA
EL MAQUILLAJE
LA LOGICA
<p> El numero PI = {{ getPi() }}</p>
<p>Radio de un círculo : 3cm </p>
<p>Área del círculo {{ (getPi() * radio*radio) }}</p>
export class AppComponent {
radio : number = 3;
getPi(): number {
return 3.14159265359;
}
}
<p> El numero PI = {{ getPi() }}</p>
<p>Radio de un círculo : 3cm </p>
<p>Área del círculo {{ (getPi() * radio*radio) }}</p>
export class AppComponent {
radio : number = 3;
getPi(): number {
return 3.14159265359;
}
}
<img
[src]="imagen.fuente"
[alt]="imagen.alt"
[title]="imagen.title"
/>
<a [href]="nuevaRuta"> pincha aquí </a>
//ts
imagen = {
fuente : "https://via.placeholder.com/600/771796",
alt : 'imagen',
title : 'cuadrado random'
}
<img
[src]="image.link"
[alt]="image.alt"
[title]="image.title"
/>
<a [href]="nuevaRuta"> pincha aquí </a>
<div [class]="clases" [id]="id"> Divs</div>
//css
.pintame {
color: red;
}
No te ha quedado cloro?
probemos el código ⬇️
<p>Num : {{num}}</p>
<button (click)="increment(1)">Sumar 1</button>
<button (click)="increment(2)">Sumar 2</button>
(click)="increment(2)"
(click)="increment(2)"
Fichero.html
Fichero.ts
Fichero.html
Fichero.ts
<p> El numero PI = {{ getPi() }}</p>
<input type="number" placeholder="Radio" [(ngModel)]="radio" />
<p>Área del círculo {{ (getPi() * radio*radio) }}</p>
export class AppComponent {
radio : number = 3;
getPi(): number {
return 3.14159265359;
}
}
¿En qué podemos utilizar esto?
Todo mezclado
export class AppComponent {
items: string[] = [];
newTask: string;
add(): void {
this.items.push(this.newTask);
this.newTask = "";
}
deleteMe(task: string): void {
this.items = this.items.filter(i => i != task);
}
}
<ul>
Lista
<li *ngFor="let item of items">
<span>{{item}}</span>
<button (click)="deleteMe(item)"> Borrar</button>
</li>
</ul>
<input placeholder="Nuevo" [(ngModel)]="newTask">
<button (click)="add()">Añadir</button>
Todo mezclado
export class AppComponent {
items: string[] = [];
newTask: string;
add(): void {
this.items.push(this.newTask);
this.newTask = "";
}
deleteMe(task: string): void {
this.items = this.items.filter(i => i != task);
}
}
<ul>
Lista
<li *ngFor="let item of items">
<span>{{item}}</span>
<button (click)="deleteMe(item)"> Borrar</button>
</li>
</ul>
<input placeholder="Nuevo" [(ngModel)]="newTask">
<button (click)="add()">Añadir</button>
Todo mezclado
export class AppComponent {
items: string[] = [];
newTask: string;
add(): void {
this.items.push(this.newTask);
this.newTask = "";
}
deleteMe(task: string): void {
this.items = this.items.filter(i => i != task);
}
}
<ul>
Lista
<li *ngFor="let item of items">
<span>{{item}}</span>
<button (click)="deleteMe(item)"> Borrar</button>
</li>
</ul>
<input placeholder="Nuevo" [(ngModel)]="newTask">
<button (click)="add()">Añadir</button>
*ngFor
Bucles con Angular (*ngFor)
<ul>
<li *ngFor="let word of stack">{{word}}</li>
</ul>
export class AppComponent {
public word : string = '';
public stack : string[] = ['Esto', 'es', 'un', 'array'];
public addTask (task: string) {
this.stack.push(task);
}
}
OJO!!! Se pone el for en el elemento que queremos que se repita!!
<ul>
<li *ngFor="let word of stack">{{word}}</li>
</ul>
export class AppComponent {
public word : string = '';
public stack : string[] = ['Esto', 'es', 'un', 'array'];
public addTask (task: string) {
this.stack.push(task);
}
}
*ngFor="let palabra of diccionario"
Primera iteración: value = array[0]
Segunda iteración: value = array[1]
Bucles con Angular (*ngFor)
<ul>
<li *ngFor="let word of stack">{{word}}</li>
</ul>
export class AppComponent {
public word : string = '';
public stack : string[] = ['Esto', 'es', 'un', 'array'];
public addTask (task: string) {
this.stack.push(task);
}
}
*ngFor="let palabra of diccionario"
Probemos lo aprendido!
https://stackblitz.com/
Bucles con Angular (*ngFor)
Haz una aplicación de gestión de tareas similar a la del gif anterior que cumpla con:
<div *ngFor="let person of people" class="card"
[ngClass]="{'underage': person.age < 18}"
[hidden]="person.age > 49">
</div>
se muestran todos, menos......? (Pregunta)
Condiciones con Angular (*ngIf)
<div *ngIf="stack.length > 0">
<ul>
<li *ngFor="let word of stack">{{word}}</li>
</ul>
</div>
<div *ngIf="stack.length == 0">
<h2>No hay ningúna entrada!</h2>
</div>
export class AppComponent {
public word : string = '';
public stack : string[] = [];
public addTask (task: string) {
this.stack.push(task);
this.word = '';
}
}
*ngIf = "condición"
Aunque no tenga los [], el ngIf espera una condición booleana.
Que le diga si se muestra o no se muestra
Condiciones con Angular (*ngIf)
<div *ngIf="stack.length > 0">
<ul>
<li *ngFor="let word of stack">{{word}}</li>
</ul>
</div>
<div *ngIf="stack.length == 0">
<h2>No hay ningúna entrada!</h2>
</div>
*ngIf = "condición"
Se muestra solo si stack tiene algo.
Sino, sale el div de debajo.
*ngIf vs [hidden]
*ngIf vs [hidden]
*ngIf vs [hidden]
<button
*ngIf="hideCompleted"
(click)="hideCompleted = !hideCompleted"
>Mostrar completados
</button>
<button
*ngIf="!hideCompleted"
(click)="hideCompleted = !hideCompleted"
>Ocultar completados
</button>
<li
[hidden]="hideCompleted && item.completed"
*ngFor="let item of items"
[ngClass]="{'completed' : item.completed}">
<span (click)="completeMe(item.title)">{{item.title}}</span>
<button (click)="deleteMe(item.title)"> Borrar</button>
</li>
desaparecerá
se hace invisible
Bucles con angular (*ngFor)
Ahora más difícil
¿y si tenemos un array de objetos?
export class AppComponent {
public people: any[] = [];
public person: any = {
name: '',
age: null,
type: ''
};
constructor() {
this.people = [
{
name: 'Pedro',
age: 15,
type: 'Young'
}, {
name: 'Borja',
age: 27,
type: 'Adult'
}, {
name: 'Yunior',
age: 50,
type: 'Old'
}
]
}
}
<div *ngIf="people.length > 0">
<div *ngFor="let person of people">
<h3>{{person.name}}</h3>
<small>Edad: {{person.age}}</small>
<br>
<small>Clase: {{person.type}}</small>
</div>
</div>
<div *ngIf="people.length == 0">
<h2>No hay ningúna entrada!</h2>
</div>
¿y si tenemos un array de objetos?
export class AppComponent {
public people: any[] = [];
public person: any = {
name: '',
age: null,
type: ''
};
constructor() {
this.people = [
{
name: 'Pedro',
age: 15,
type: 'Young'
}, {
name: 'Borja',
age: 27,
type: 'Adult'
}, {
name: 'Yunior',
age: 50,
type: 'Old'
}
]
}
}
Fácil y rápido!!!
Pruébalo sin miedo y juega con él!
Haz una aplicación de gestión de tareas que cumpla con:
[ngClass]="{ 'nombre-clase' : condicion }"
export class AppComponent {
users = [
{name : "Yunior" , role : 'teacher'},
{name : "María" , role : 'student'}
]
}
<div *ngFor="let user of users"
[ngClass]="{ 'teacher' : user.role === 'teacher' }"
class="user">
<h2>{{user.name}}</h2>
</div>
Apliquemos esto a nuestro ejemplo anterior
Probamos reutilizando el código de antes
<!-- HTML -->
<div *ngIf="people.length > 0">
<div *ngFor="let person of people" class="card" [ngClass]="{'underage': person.age < 18}">
<h3>{{person.name}}</h3>
<small>Edad: {{person.age}}</small>
<br>
<small>Clase: {{person.type}}</small>
</div>
</div>
//CSS
.card {
border: 1px solid black;
border-radius: 10px;
width: 25%;
margin-top: 10px;
padding: 10px 20px;
}
.underage {
border: 2px solid red;
}
*ngfor no puede estar junto a un *ngIf
*ngfor no puede estar junto a un *ngIf
<li
*ngIf="!hideCompleted || !item.completed"
*ngFor="let item of items"
[ngClass]="{'completed' : item.completed}">
<span (click)="completeMe(item.title)">{{item.title}}</span>
<button (click)="deleteMe(item.title)"> Borrar</button>
</li>
*ngfor no puede estar junto a un *ngIf
<li
[hidden]="hideCompleted && item.completed"
*ngFor="let item of items"
[ngClass]="{'completed' : item.completed}">
<span (click)="completeMe(item.title)">{{item.title}}</span>
<button (click)="deleteMe(item.title)"> Borrar</button>
</li>
Practicamos todo lo aprendido hoy. Mejoramos nuestra app de lista de tareas haciendo uso de los *ngIf *ngFor [ngClass] [hidden] (click) (mouseover) (keyup.enter), etc etc