Accede a tu cuenta de Google Firebase o créala. Firebase es la base de datos en tiempo real de Google.
Una vez que tenga su cuenta lista, cree un nuevo proyecto llamado «todoer». Después de esto, haz clic en «Añadir Firebase a tu aplicación web». Esto te proporcionará toda la información de la API para conectarte a la Firebase. Debería verse algo como esto:
1234567891011<script src="https://www.gstatic.com/firebasejs/3.1.0/firebase.js"</script><script> // Inicializar la Base de Fuego var config = { apiKey: "AIzaSyBBiOO44HzgIdsnzWG8JCic3MmEgsdfJ", authDomain: "todoer.firebaseapp.com", base de datosURL: "https://todoer.firebaseio.com", storageBucket: "", }; firebase.initializeApp(config);</script>
Copia eso y guárdalo para más tarde.
Ahora ve a la base de datos y selecciona reglas . La base de fuego por defecto requiere que estés autentificado. Vamos a cambiar eso para que cualquiera pueda acceder a nuestra aplicación, y añadiremos la autenticación más tarde. De esta manera podemos hacer nuestra funcionalidad principal sin tener que escribir un nombre de usuario y una contraseña cada vez que nos ejecutamos. Recuerden que esto se cambiará más tarde.
Publica tus reglas ajustadas usando el siguiente comando:
123456{ "reglas": { ".read": true, ".write": true }}
Selecciona los datos y añade la tecla «todos» y el valor de $0027$0027 al árbol.
Configuración de la base de fuego
Abra su archivo www/index.html, y pegue la información de configuración de la Base de Fuego después de su etiqueta y antes de sus otras etiquetas de secuencia de comandos.
12345678910111213141516171819202122232425262728293031323334353637383940414243<! DOCTYPE html;<html lang="en" dir="ltr"><head;w;title</title&; <meta charset="UTF-8">meta name="viewport" content="width=ancho del dispositivo, escala inicial=1.0, escala mínima=1.0, escala máxima=1. 0, user-scalable=no"> <meta name="format-detection" content="telephone=no"> <meta name="msapplication-tap-highlight" content="no"> <link ios- > <link md- > <link wp- >/head <body; <ion-app;</ion-app;<! -- Iniciar Añadir --; -- script src="https://www.gstatic.com/firebasejs/3.1.0/firebase.js">/script=; -- script=; // Iniciar Base de Fuego var config = { apiKey: "AIzaSyBBiOO44HzgIdsnzWG8JCic3MmEgsdfJ", authDomain: "todoer.firebaseapp.com", base de datosURL: "https://todoer.firebaseio.com", storageBucket: "", }; firebase.initializeApp(config); </script > <!-- End Add --; <!-- cordova.js requerido para las aplicaciones de cordova --; <script src="cordova. js"/script="polyfill" necesario para las plataformas sin soporte de Promesa y Cobro --; <script src="build/js/es6-shim.min.js "¡;www. cordova.com! -- Zone.js y Reflect-metadata -- --; ¡¡¡Script src="build/js/Reflect.js"--;!! -- el paquete que se construye a partir del código fuente de la aplicación --; <script src="build/js/app.bundle.js"--;--"script";--;--"body";--;--"html";
La base de fuego está lista para funcionar.
Creación del servicio de datos
Para actuar como nuestro mediador entre la base de fuego y nuestra aplicación vamos a construir un servicio de datos. Para el propósito de esta guía estaremos alojando todos nuestros datos en un servicio. Para aplicaciones más grandes puede que quiera dividir esto en múltiples servicios.
Primero vamos a crear un proveedor.
1$ ionic g provider data
Esto creará un componente @inyectable que inyectaremos en la raíz de nuestra aplicación. ¿Por qué en la raíz? Queremos que este servicio viva durante toda la vida de nuestra aplicación, y no cada vez que cargamos una página. Los proveedores que se inyectan por componente se crean en el momento de la inyección. Así que si queremos que nuestros datos persistan, debemos inyectarlos en el componente principal de la aplicación.
Abre el archivo app.ts y en la parte superior agrega:
1importar {Datos} de $0027./proveedores/datos/datos$0027;
Luego en el componente agregar los datos a los proveedores;
123@componente({ proveedores: [Datos]});
Referencia de la base de fuego
La Base de Fuego es una base de datos nosql en tiempo real. La forma en que accedemos a los datos en ella es por una ruta de consulta. Por ejemplo, si nuestros datos se ven así.
123456789101112{ todos: { $todoId: { título: $0027todo1$0027, completo: falso }, $todoId: { título: $0027todo2$0027, completo: verdadero } }}
La forma en que podríamos acceder a nuestra lista de todos podría ser firebase.database().ref($0027/todos$0027); Si quisiéramos obtener un todo específico usaríamos firebase.database().ref($0027/todos/$todoId$0027); donde $todoId es el id único del todo. Todos los datos de la base de fuego se almacenan como un objeto.
Entonces, agreguemos la base de fuego al proveedor de datos
123456789101112importación {inyectable] de $0027@angular/núcleo$0027;@inyectable()clase de exportación Datos {privado _db: cualquiera; privado _todosRef: cualquiera; constructor() { this._db = base de fuego. database().ref($0027/$0027); // Obtener una referencia de la base de fuego a la raíz this._todosRef = firebase.database().ref($0027todos$0027); // Obtener una referencia de la base de fuego a los todos }
Ahora que tenemos nuestras referencias en la base de datos, ¿cómo obtenemos los datos?
Consultas sobre la base de fuego
La Base de Fuego tiene un sistema de consulta de base de eventos que le permite configurar los oyentes para ciertos eventos. Para nuestro caso de uso, vamos a escuchar el evento child_added. Para obtener una lista completa de eventos, consulte la documentación de la API de la Firebase.
Añadamos la consulta al constructor de nuestra clase de servicio de datos.
123456789101112131415161718importar {inyectable] desde $0027@angular/core$0027;@inyectable()exportar clase Data { private _db: any; private _todosRef: any; constructor() { this._db = firebase.database().ref($0027/$0027); // Obtener una referencia de la base de fuego a la raíz esto. _todosRef = firebase.database().ref($0027todos$0027); // Obtener una referencia de la base de fuego a la todos this._todosRef.on($0027child_added$0027, this.handleData, this); // ***ADD THIS LINE*** } handleData(snap) { //Do algo con los datos }}
La línea que añadimos a nuestro constructor establece un oyente para cuando un niño se añade a la ruta de todos. this.handleData se pasa para manejar la instantánea de datos enviada desde la Base de Fuego. Por último, pasamos esto como el contexto para nuestra función de handler.
Observadores y Observables
Para que nuestra aplicación se sienta lo más cercana posible al tiempo real, vamos a hacer uso del patrón de observación. Los observadores están incorporados en Angular 2 y (en el momento de escribir este artículo) utilizan RxJS (biblioteca ReactiveX para JavaScript). Sin embargo, esa biblioteca será reemplazada por la implementación de la propia biblioteca de Angular.
El concepto del patrón es bastante simple. Un observador puede suscribirse y «observar» a un observable. Cuando los datos son empujados al observable, el observador los recibe hasta que el observable termina. Para simplificar, la relación observable-observable es un patrón de publicación-suscripción.
Ahora que entendemos a los observadores, sigamos con nuestra aplicación. En su clase de datos, cree un ReplaySubject. ¿Qué es un ReplaySubject? Un Sujeto es tanto un Observador como un Observable. Normalmente un observable sólo enviará el último evento a un nuevo suscriptor. Un ReplaySubject sin embargo, enviará cada mensaje a un nuevo suscriptor en el orden en que fueron enviados. Un poco menos eficiente, pero de esta manera no nos perderemos ningún viejo todos.
12345678910111213141516171819202122232425262728293031importar {inyectable] de $0027@angular/core$0027;importar {ReplaySubject} de $0027rxjs/ReplaySubject$0027;@Injectable()exportar clase Data {privada _todos$: any; privada _db: any; privada _todosRef: any; constructor() { this. _db = firebase.database().ref($0027/$0027); this. _todosRef = firebase.database().ref($0027todos$0027); this._todosRef.on($0027child_added$0027, this.handleData, this); this._todos$ = new ReplaySubject(); } get todos() { return this. _todos$; } handleData(snap) { try { // Dile a nuestro observador que tenemos nuevos datos this._todos$.next(snap.val()); } catch (error) { console.log($0027catching$0027, error); } }}
En nuestra función handleData(), vamos a obtener una instantánea (por lo tanto, una instantánea) de los datos de nuestra base de datos. Llamando a la función .val() podemos obtener el valor asociado a esa instantánea y se la pasaremos a nuestros observadores. this._todos$.next(data) envía los nuevos datos a todos los que estén preparados para escucharlos.
Creando una tarea
Cada vez que se crea un todo queremos que nuestra aplicación actualice la base de datos. Así que vamos a añadir una función a nuestro proveedor de datos que guarda un todo.
En su archivo data.ts, añada el siguiente método:
1234save(todo){ devuelve esto._todosRef.push(todo).key;}
La función de empuje añadirá un nuevo todo a la Base de Fuego, generará una llave para ella, y devolverá esa llave a través de la propiedad .key.
Ahora, genera una nueva página usando este comando de shell iónico.$ ionic g page new-todo
Deberías tener tres nuevos archivos: new-todo.ts, new-todo.html, y new-todo.scss. Abre primero el archivo new-todo.ts, y añade nuestro servicio de datos.
12345678910111213141516importar {Componente} de $0027@angular/núcleo$0027;importar {Controlador Naval} de $0027ionic-angular$0027;importar {Datos} de $0027../../proveedores/datos/datos$0027;/* Clase generada para la página NewTodoPage. Ver http://ionicframework.com/docs/v2/components/#navigation para más información sobre las páginas iónicas y la navegación.*/@Componente({ templateUrl: $0027build/pages/new-todo/new-todo.html$0027,})clase de exportación NewTodoPage { constructor(public nav: NavController, public _data: Data) {}}
En la parte superior vamos a importar nuestro servicio de datos. Luego en el constructor vamos a crear una referencia al servicio de datos.
Ahora nuestro todo tiene una estructura definida, y sabemos cuáles serán nuestros tipos de datos. Así que, hagamos un objeto de clase para nuestro todo. Antes de que su clase NewTodoPage agregue:
12345678class Todo { título público: cadena; público completado: booleano; constructor() { this.title = $0027$0027; this.completed = false; }}
Luego agrega una variable de miembro a la clase NewTodoPage que tiene un tipo de Todo.
123456clase de exportación NewTodoPage { todo: Todo; constructor(public nav: NavController, public _data: Data) { this.todo = new Todo(); }}
Definimos un nuevo todo cada vez que se llama al constructor para asegurarnos de que este… todo no esté indefinido.
A continuación viene el método save(). En la clase NewTodoPage agrega:
1234567save() { var key = this._data.save(this.todo); if(key) { console.log($0027saved$0027); }}
Revisamos la llave para asegurarnos de que nuestro empuje fue exitoso. La base de fuego volverá nula si no creó el «todo» .
Eso es todo por ahora en nuestra clase de NewTodoPage. Veamos el html a continuación.
1234567<ion-navbar *navbar;
Bastante vacío. Añadamos nuestros elementos de entrada. Vamos a usar una lista de iones y poner nuestros elementos de entrada en los elementos de la lista.
en nuestro
1234567891011 <ion-list;³³³ón-item;³³³ón-label flotante;³³³ón-title:³³³ón-label;³³³ón-entrada [(ngModel)]="todo". complete"/ion-checkbox, Así que, aquí vemos algunas cosas nuevas de Angular 2. La sintaxis para el modelo ng ha cambiado a [(ngModel)]. Esta nueva sintaxis es una expresión de su modelo de unión. {{}} y [] son uniones unidireccionales de la fuente de datos a la vista y () son uniones unidireccionales de la vista a la fuente de datos. La combinación [()] es una unión de dos direcciones . Así que nuestro título y completo están ligados tanto a la fuente de datos como a la vista, de ahí la naturaleza en tiempo real de la aplicación.Ahora vamos a discutir (click), una especie de declaración. Las declaraciones responden a eventos planteados por el elemento, directiva o componente al que están vinculados. En nuestro caso, ese evento es un clic levantado por el elemento botón. Como está envuelto en () sabemos que sólo va a enviar datos en una dirección; de nuestra veiw a nuestro componente.
Para una mirada más profunda a las declaraciones, mira los documentos de Angular 2.
Ahora, si nuestro usuario hace un todo, no tiene forma de saber si tuvo éxito. Así que vamos a añadir algunos comentarios de los usuarios.
Ionic 2 tiene un montón de bonitos componentes incorporados para elegir, incluyendo el componente Toast. Las tostadas son una gran manera de proporcionar retroalimentación. Para añadir un brindis a nuestra nueva página de "Todo", primero tendremos que importar los brindis de Ionic 2.
1import {NavController, Toast} de $0027ionic-angular$0027;En nuestro método save(), vamos a añadir:
123456789101112131415var key = this._data.save(todo); if(key) { let toast = Toast.create({ message: $0027Todo Saved$0027, duration: 500 }); toast.onDismiss(() = > { this.nav.pop() console.log($0027Dismissed toast$0027); }); this.nav.present(toast); }Si recibimos una llave de la Base de Fuego, crearemos un nuevo brindis y lo presentaremos. Una vez disimulada, quitaremos la página de la pila.
El enrutamiento de Ionic 2 funciona como una pila; se empuja en las nuevas vistas y se sacan las viejas.
Home (push) => New Todo (push) => otherView <= el usuario ve, pero las otras vistas siguen ahí.
Cuando el usuario pulsa el botón de retroceso, el estado superior sale de la pila.
Inicio (push) => Nuevo Todo (pop) <= el usuario ve.
Una vez que hagamos nuestros "todos", querremos verlos en nuestra lista, ¿verdad? Hagámoslo ahora.
Listado de todos
En lugar de generar una nueva página para la lista, vamos a utilizar la página de inicio existente. De esta manera, tan pronto como un usuario accede a la aplicación, ve su todos.
Como con la nueva página vamos a añadir el servicio de datos al constructor. También vamos a añadir una subscipción a nuestro todo observable, así que tendremos actualizaciones tan pronto como ocurran.
12345678910111213141516171819importar {Componente} desde "@angular/núcleo";importar {NavController} desde $0027ionic-angular$0027;importar {Datos} desde $0027../../proveedores/datos/datos$0027;importar {NewTodoPage} desde $0027../new-todo/new-todo$0027;@Componente({ templateUrl: $0027build/pages/home/home. html$0027})exportar clase HomePage { public todos: any[] = []; constructor(private _navController: NavController, private _data: Data) { let that = this; this. _data.todos.subscribe((data) = > {that.todos.push(data);}, (err) = > {console.error(err);}); } newTodo() { this._navController.push(NewTodoPage); }}Fíjate que también importamos nuestra página de novedades, y añadimos un nuevo método Todo. Esto es lo que llamaremos cuando cambiemos a la nueva página Todo. En ese método, llamaremos al método de empuje de nuestro controlador de navegación.
Ahora que tenemos nuestros datos listos, vamos a renderizarlos. En nuestro html tendremos esto:
12345678910111213141516<ion-navbar *navbar¿; <ion-title¿; Ionic 2 Todo App </ion-title¿;/ion-navbar¿;;ion-content¿;ion-list¿;*ngIf="todos"`; <ion-item *ngFor="let todo of all"``; <ion-label¿;{{todo. título}}</ion-label,} {{ ngModel]]="todo.completo"};} { { { {i1}y la lista de iones.} todos "*; No todos </promedio; fab-botón fab-botón fab-derecha (click)="newTodo() "*; NuevoAlgunos nuevos conceptos aquí: El nuevo *ngIf de Angular2 se utiliza, en oposición al ng-hide y ng-show de Angular 1, para comprobar si tenemos todos para mostrar.
Si tenemos todos para mostrar, haremos un bucle a través de nuestros todos usando el *ngFor reemplazo de ng-repeat. Luego mostramos nuestro todo usando la sintaxis bidireccional de ngModel que vimos antes.
Si no tenemos todos, estamos haciendo un simple párrafo para decirle al usuario que no tenemos todos para mostrar. Luego llamamos al método newTodo() que creamos antes para que nos lleve a crear un todo.
Puede que se pregunte sobre el * antes de estas directivas. Esa es la sintaxis que Angular 2 usa para ayudar a leer y escribir directivas que modifican el html.
Ahora ejecuta el servicio iónico desde tu línea de comandos para iniciar nuestra aplicación y compruébalo.
¡Eso concluye la primera parte! En la parte 2, editaremos un todo y añadiremos la autenticación de usuario.
Gracias por leer este tutorial. Por favor, vota si lo encuentras útil y/o interesante. También, siéntase libre de hacer comentarios y dar retroalimentación en la sección de discusión a continuación.