Desarrollar una aplicación híbrida utilizando tecnologías que integren modelos de aprendizaje automático previamente entrenados en un entorno funcional y accesible para resolver problemas específicos mediante el reconocimiento de patrones, objetos o sonidos fomentando habilidades prácticas en el desarrollo de aplicaciones móviles con tecnologías modernas y la implementación de inteligencia artificial.
Instale los paquetes de su proyecto con:
npm i
Levante los servicios, con:
ionic serve
Edite el archivo src/app/tabs/tabs.page.ts, con:
...
/* 1. Importe la referencia al ícono peopleCircle */
import { clipboardOutline, ... } from 'ionicons/icons';
...
export class TabsPage {
...
constructor() {
/* 2. Agregue el ícono peopleCircle */
addIcons({ clipboardOutline, ... });
}
}
Edite el archivo src/app/tabs/tabs.page.html, con:
<ion-tabs>
<ion-tab-bar slot="bottom">
...
<ion-tab-button tab="tab2" href="/tabs/tab2">
<!-- 1. Ícono y nombre del tab -->
<ion-icon name="clipboard-outline"></ion-icon>
<ion-label>Opinión</ion-label>
</ion-tab-button>
</ion-tab-bar>
</ion-tabs>
(STOP 1) Compruebe el resultado en el navegador.
Edite el archivo src/app/tab2/tab2.page.ts, con:
...
import {
/* Importe los componentes de la UI */
IonCard, IonCardHeader, IonCardTitle, IonCardContent,
IonSelect, IonSelectOption, IonTextarea,IonButton,
IonList, IonItem, IonLabel,
...
} from '@ionic/angular/standalone';
@Component({
...
imports: [
/* Registre los componentes de la UI */
IonCard, IonCardHeader, IonCardTitle, IonCardContent,
IonSelect, IonSelectOption, IonTextarea,IonButton,
IonList, IonItem, IonLabel,
...
]
})
export class Tab2Page { ... }
Reemplace todo el contenido en el archivo src/app/tab2/tab2.page.html, por:
<ion-header [translucent]="true">
<ion-toolbar>
<ion-title>
Retroalimentación
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content [fullscreen]="true">
<ion-card class="ion-padding-bottom ion-margin-bottom">
<ion-card-header>
<ion-card-title>Su opinión es importante</ion-card-title>
</ion-card-header>
<ion-card-content class="ion-text-center">
<form>
<ion-select label="Calificación" placeholder="Seleccione un valor">
<ion-select-option value="bueno">Bueno</ion-select-option>
<ion-select-option value="regular">Regular</ion-select-option>
<ion-select-option value="malo">Malo</ion-select-option>
</ion-select>
<ion-textarea label="Opinión" placeholder="Agregue aquí su descripción"></ion-textarea>
<ion-button type="submit">Enviar</ion-button>
</form>
</ion-card-content>
</ion-card>
<ion-card class="ion-padding-bottom ion-margin-bottom">
<ion-card-header>
<ion-card-title>Opiniones</ion-card-title>
</ion-card-header>
<ion-card-content>
<ion-list>
<!-- CARGA DE DATOS - INICIO -->
<!-- CARGA DE DATOS - FIN -->
</ion-list>
</ion-card-content>
</ion-card>
</ion-content>
(STOP 2) Compruebe el resultado en el navegador.
Edite el archivo src/app/tab2/tab2.page.ts, con:
...
/* Importe el módulo para formularios reactivos */
import { ReactiveFormsModule } from '@angular/forms';
@Component({
...
imports: [
/* Registre el módulo para formularios reactivos */
ReactiveFormsModule,
...
]
})
export class Tab2Page { ... }
...
/* Importe los constructores del formulario */
import { FormGroup, FormControl, Validators } from '@angular/forms';
@Component({ ... })
export class Tab2Page {
/* Instancie un formulario */
myForm: FormGroup = new FormGroup({
score: new FormControl("", Validators.required),
opinion: new FormControl("", Validators.required)
});
}
Edite el archivo src/app/tab2/tab2.page.html, con:
...
<form [formGroup]="myForm">
<ion-select formControlName="score" ... > ... </ion-select>
<ion-textarea formControlName="opinion" ... > ... </ion-textarea>
<ion-button type="submit" [disabled]="!myForm.valid"> ... </ion-button>
</form>
...
(STOP 3) Compruebe el resultado en el navegador.
Edite el archivo src/app/tab2/tab2.page.ts, con:
...
export class Tab2Page {
...
/* El método onSubmit para enviar los datos del formulario mediante el servicio */
onSubmit() {
console.log(this.myForm.value);
alert(this.myForm.controls["score"].value)
this.myForm.reset()
}
}
Edite el archivo src/app/tab2/tab2.page.html, con:
...
<form ... (ngSubmit)="onSubmit()">
...
</form>
(STOP 4) Compruebe el resultado en el navegador.
Cree el archivo src/credentials.ts, con:
export const firebaseConfig = {
apiKey: "<APIKEY>",
authDomain: "<AUTHDOMAIN>",
projectId: "<PROJECTID>",
storageBucket: "<STORAGEBUCKET>",
messagingSenderId: "<MESSAGINGSENDERID>",
appId: "<APPID>"
};
Edite el .gitignore, con:
...
/src/credentials.ts
Instale los módulos firebase y @angular/fire, con:
npm install firebase @angular/fire
Edite main.ts, con:
...
/* Importe las credenciales */
import { firebaseConfig } from './credentials';
/* Importe los módulos de AngularFire */
import { provideFirebaseApp, initializeApp } from '@angular/fire/app';
import { provideFirestore, getFirestore } from '@angular/fire/firestore';
bootstrapApplication(AppComponent, {
providers: [
...
/* Inyecte los módulos de AngularFire */
provideFirebaseApp(() => initializeApp(firebaseConfig)),
provideFirestore(() => getFirestore()),
],
});
(STOP 5) Compruebe la importación de los paquetes en el package.json y que el archivo credentials no se encuentre versionado.
Desde la línea de comandos, cree el servicio proveedor de datos, con:
ionic g service services/provider
Edite el servicio src/app/services/provider.service.ts, con:
/* Agregue la función inject */
import { Injectable, inject } from '@angular/core';
/* Importe los módulos de AngularFire */
import { Firestore, collection, addDoc, collectionData } from '@angular/fire/firestore';
import { Observable } from 'rxjs';
...
export class ProviderService {
/* Inyecte de dependencia AngularFire */
firestoreService = inject(Firestore);
constructor() { }
}
...
export class ProviderService {
constructor(...) { }
/* Método para crear un documento en la colección */
createDocument(collectionName: string, data: any): Promise<any> {
const colRef = collection(this.firestoreService, collectionName);
return addDoc(colRef, data);
}
}
Edite src/app/tab2/tab2.page.ts, con:
...
/* Importe el servicio */
import { ProviderService } from '../services/provider.service';
@Component({ ... })
export class Tab2Page {
...
/* Nombre de la colección */
collectionName = 'reviews';
/* Inyecte la dependencia a Firestore */
constructor(private providerService: ProviderService) { }
/* El método onSubmit para enviar los datos del formulario mediante el servicio */
onSubmit() {
this.providerService.createDocument(this.collectionName, this.myForm.value).then(() => {
this.myForm.reset()
});
}
}
(STOP 6) Compruebe el funcionamiento en el navegador y el resultado en Firestore.
Edite src/app/services/provider.service.ts, con:
...
export class ProviderService {
constructor(...) { }
createDocument(...): Promise<any> { ... }
/* Método para leer una colección */
readCollection(collectionName: string): Observable<any[]> {
const colRef = collection(this.firestoreService, collectionName);
return collectionData(colRef, { idField: 'id' });
}
}
Edite src/app/tab2/tab2.page.ts, con:
...
export class Tab2Page {
...
/* Arreglo con datos locales */
dataList: any[] = [];
constructor( ... ) { }
onSubmit() { ... }
/* Al inicializar, carga los datos */
ngOnInit() {
this.loadData();
}
loadData() {
this.providerService.readCollection(this.collectionName).subscribe((data) => {
this.dataList = data;
});
}
}
Edite src/app/tab2/tab2.page.html, con:
<ion-header [translucent]="true">
...
</ion-header>
<ion-content [fullscreen]="true">
<ion-card class="ion-padding-bottom ion-margin-bottom">
...
</ion-card>
<ion-card class="ion-padding-bottom ion-margin-bottom">
<ion-card-header>
<ion-card-title>Opiniones</ion-card-title>
</ion-card-header>
<ion-card-content>
<ion-list>
<!-- CARGA DE DATOS - INICIO -->
@for (datum of dataList; track $index) {
<ion-item>
<ion-label> {{ datum?.score }} </ion-label>
<ion-label> {{ datum?.opinion }} </ion-label>
</ion-item>
}
<!-- CARGA DE DATOS - FIN -->
</ion-list>
</ion-card-content>
</ion-card>
</ion-content>
(STOP 7) Compruebe el funcionamiento en el navegador.
🧵#HowToAngular
— Alfredo (@brolag) May 11, 2021
¿Cuáles son los patrones de diseño que te van a ayudar a entender #Angular a profundidad?
- Module
- Observer
- Dependency Injection
- Singleton
- Decorator
- Factory
- Adapter
- Facade
Exacto. Está no es una guía "Convierte en Angular Dev en 30 min" 😉 pic.twitter.com/pZh1wJiI5t
formularios reactivos, directivas, servicios