{"id":18244742,"url":"https://github.com/devdevi/angular-6","last_synced_at":"2025-04-08T18:48:13.623Z","repository":{"id":37194283,"uuid":"241248045","full_name":"devdevi/angular-6","owner":"devdevi","description":"angular","archived":false,"fork":false,"pushed_at":"2023-01-07T14:57:46.000Z","size":15819,"stargazers_count":0,"open_issues_count":25,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-14T14:53:30.483Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/devdevi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-02-18T01:46:43.000Z","updated_at":"2020-04-07T02:23:12.000Z","dependencies_parsed_at":"2023-02-07T11:45:18.562Z","dependency_job_id":null,"html_url":"https://github.com/devdevi/angular-6","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devdevi%2Fangular-6","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devdevi%2Fangular-6/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devdevi%2Fangular-6/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devdevi%2Fangular-6/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/devdevi","download_url":"https://codeload.github.com/devdevi/angular-6/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247909107,"owners_count":21016475,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-05T09:17:28.490Z","updated_at":"2025-04-08T18:48:13.595Z","avatar_url":"https://github.com/devdevi.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Messenger\n\nThis project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 9.0.2.\n\n## Development server\n\nRun `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.\n\n## Code scaffolding\n\nRun `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.\n\n## Build\n\nRun `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.\n\n## Running unit tests\n\nRun `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).\n\n## Running end-to-end tests\n\nRun `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).\n\n## Further help\n\nTo get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).\n\n\n\n¿Qué tienen Angular, React y Vue en común?\nTodos están orientados al desarrollo del frontend.\n\nTodos están orientados al desarrollo de aplicaciones de tipo SPA (Single Page Application).\n\nUna vez se aprenda uno ya cualquiera de los otros dos se hará fácil.\n\nPueden ser utilizadas para el desarrollo de aplicaciones mobiles.\n\nCurva de Aprendizaje\nAngular: Curva de aprendizaje más alta.\n\nReact: Es mucho más fácil de aprender que Angular.\n\nVue: Es aun más fácil debido a que sus librerías son muy parecidas.\n\nProyectos de gran escala\nAngular: Tiene mucha más ventaja por la cantidad de componentes que tiene que pueden manejar y fue concebido para el desarrollo de aplicaciones de alta escala.\n-React: react al igual que angular es usado para el desarrollo de aplicaciones grandes.\n-Vue: No es tan robusto, sin embargo es recomendable usarlo para aplicaciones en despliegue legacy que ya tengan mucho desarrollo y requieren actualizarse a aplicaciones tipo SPA o hacer algún tipo de integración.\n\nHerramientas de desarrollo\nAngular: Typescript le da mucha ventaja por el uso de reglas de alto tipado, de igual forma vue y react pueden integrarse a TypeScript sin embargo no es obligatorio, esto de alguna forma obliga al desarrollador a tener un código mejor estructurado y limpio.\n\nReact: Tiene herramientas para el debug de codigo que son extensiones del navegador (Chrome y Firefox) React Developer Tools.\n\nMantenimiento de código\nAngular: Es mucho más complejo en detección de bugs causados por sus mismos componentes.\n-React y Vue: Son mucho más facil y flexible en la detección de errores.\n\nFlexibilidad\nAngular: por la cantidad de componentes que posee angular a veces se descargan una cantidad amplia de elementos que no necesariamente serán usados, esto lo hace poco flexible si se desea desarrollar aplicaciones pequeñas.\n\nReact y Vue: tienen pocas librerias y se adaptan a aplicaciones pequeñas y grandes.\n\nDesarrollo mobile\nAngular: Tiene framework de desarrollo híbrido como Ionic, que igualmente pueden integrarse a React y Vue en su ultima versión. La ventaja que tiene este framework basado en angular es que no genera aplicaciones nativas.\n\nReact: React usa react native y es un desarrollo no 100% nativo pero se acerca a dicho desarrollo y lo hace mucho más optimo.\n-Vue: Usa NativeScript -. Vue permite la creación de aplicaciones nativas con NativeScript y Vue.\n\n### Que hace esta app:\n-app de mensajería instantánea, chat de persona a persona\n-debe te\n### Explorando el sistema de archivos\n-A primera vista la estructura de los archivos del proyecto pudiera ser un tanto abrumadora ya que Angular necesita una gran cantidad de elementos y dependencias para proveernos del entorno adecuado para el desarrollo, pero al generar el entorno de producción, la mayoría de estas dependencias no estarán incluidas, por lo que la estructura final será mucho más sencilla.\n\nComo parte de la estructura del proyecto econtramos el archivo /package.json/ y el directorio /npm_modules. Este directorio contiene un numero importante de sub-carpetas con los paquetes de todas las dependencias usadas por node para generar nuestra app y sus versiones específicas. Es muy recomendable instalar los paquetes del proyecto con la bandera npm install \u003cnombre del paquete\u003e --save-exact para evitar incompatibilidades con futuras versiones de los mismos paquetes.\n\nLa carpeta /src contienen los archivos con el código que vamos a editar. Los más importantes son: los css, el index.html que es donde corre toda la aplicación ya que, como vimos, Angular genera una SPA (aplicación de una sóla página).\nTambién encontramos la carpeta /app donde están los archivos principales, que editaremos para crear nuestra aplicación, como es el caso de: app.component.css, app.component.html, app.component.spec.ts, app.component.ts y app.modules.ts.\nTenemos también la carpeta /assets, que con tiene todos los recursos estáticos usados por la aplicación\n### Navegación básica entre componentes\nPara implementar ruteo, que es la capacidad de navegar entre componentes (vistas) en Angular, es necesario importar Routes desde @angular/router en el componente base de nuestra app:\n\nimport { Routes } from '@angular/router';\nLuego se deben declarar todas las rutas que vamos a usar en una constante de tipo Routes:\n\n```\nconst appRoutes: Routes = [\n  { path: '', component: HomeComponent },\n  { path: 'home', component: HomeComponent },\n  { path: 'login', component: LoginComponent }\n];\n```\nSe incluyen todas las rutas definidas como elementos de un arreglo de objetos json de JS.\nLa propiedad path va a comparar el segmento coincidente en la url, mientras que component indica hacia cuál componente se va a navegar.\n\nPara hacer funcionar las rutas en nuestra app, se debe importar el módulo RouterModule en la sección imports del app.component.ts ya que éste no se importa de manera automática.\n\nFinalmente para implementar la navegación en nuestra app, es necesario indicar en el contenido de app.component.html una directiva \u003crouter-outlet\u003e\u003c/router-outlet\u003e que se utilizará para inyectar eventualmente los componentes de toda la navegación que hemos definido. Todo lo que se coloque en el html, fuera de esta directiva, quedará fijado como contenido común en todas las vistas de nuestra navegación.\n\nEs importante tener en cuenta que al usar enlaces o anclas ( \u003ca\u003e ``` \u003c/a\u003e ) de html, tendremos que sustituir el atributo href por routerLink, que es parte de RouterModule, para evitar la recarga completa de la página y la latencia, ya que esto iría en contra del concepto fundamental de lo que es una SPA (single page app).\n### ¿Cómo usar tipos de datos con TypeScript?\nTypeScript debe su nombre a los tipos de datos (types en inglés). JavaScript no es un lenguaje de programación tipado, por lo que es requerida en su sintaxis la definición de un tipo de dato al momento de instanciar las clases o variables en general. El uso de tipos explícitos en la programación permite a fin de cuentas un mejor aprovechamiento del recurso de memoria, entre muchos otros beneficios.\n\nLos tipos básicos (built-in y definidos por el usuario) admitidos por TypeScript son: Boolean, Number, String, Array, Tuple, Enum, Void, Null y Undefined, y el tipo que es la base de todos los anteriores: Any, que básicamente representa cualquier cosa.\n\nLos tipos de datos avanzados de Type\nScript incluyen: Function, Object, Interface, Guard, Union, entre otros.\n\n\n### Qué son las interfaces de TypeScript y su implementación\nLos tipos de datos Interfaces de TypScript, son muy parecidos a una clase, en la que se definen propiedades internas que pueden ser de cualquiera de los otros tipos. Estas propiedades internas pueden definirse como obligatorias u opcionales usando el símbolo “”?\"\". Las interfaces definen en cierto modo estructuras personalizadas de datos en las que lo principal es que al ser implementadas usando ciertas IDEs (como Webstorm), muestran mensajes de control y validación para asegurar el uso adecuado de dicha interface, en tiempo real durante el desarrollo.\n\nLa forma de declarar una interface se puede ver en el siguiente ejemplo:\n\nexport interface User {\n  nick: string,\n  subnick?: string,\n  age?: number,\n  email: string,\n  friend: boolean,\n  uid: any\n}\n\n\n### NgFor aplicado en la lista de usuarios\nNgFor es una directiva estructural que afecta (agrega, modifica o elimina) un elemento HTML. Las directivas estructurales las identificamos porque llevan un * antes de la directiva, por ejemplo: *ngFor\n\nNgFor nos permite recorrer un arreglo de datos y por cada elemento generar o imprimir en el DOM un elemento HTML nuevo, con algún valor cambiado basado en el elemento leído del arreglo.\n### NgIf aplicado en la lista de usuarios\nNgIF es una directiva estructural de Angular que evalúa un valor o una expresión buleana, en función de la cual se mostrará o no, un elemento HTML. El elemento se mostrará sólo cuando la condición sea verdadera (true).\n### Navegación con parámetros\nAl navegar entre pantallas, hay ocasiones en las que es necesario pasar datos particulares. Usando routerLink podemos incluir parámetros de manera similar a como lo hacemos con subdominios o subdirectorios. Para recibir e interpretar estos parámetros correctamente es necesario definir las rutas específicas en appRoutes y consultarlos luego en el componente con el objeto ActivatedRoute.\n### Accediendo a nuestros usuarios desde Conversation.ts\n\nPara tener acceso al detalle de los usuarios en diferentes componentes podemos implementar una de dos soluciones:\n\nDuplicar la fuente de datos en los dos (o más) componentes (no recomendada)\nTener una sola fuente de datos a la que pueden acceder varios componentes (recomendada)\n\n### Creando un servicio de usuarios e Inyectando el servicio en nuestros componentes\nUn servicio es una clase que puede ser inyectada en uno o varios componentes y que es muy útil para compartir datos o funciones entre éstos, evitando la duplicidad de código.\n\nSe crean a través del Angular CLI con el siguiente comando:\n\nng generate service \u003cdirectorio\u003e/\u003cnombre del servicio\u003e\nAl ejecutar este comando se generan en nuestro proyecto los siguientes archivos:\n\n/\u003cdirectorio\u003e\n  \u003cnombre del servicio\u003e.service.spec.ts\n  \u003cnombre del servicio\u003e.service.ts\nLuego en el componente, inyectamos el Servicio de manera similar a cómo inyectamos el ActivatedRoute.\n\nLos services en Angular son para que en ellos puedas hacer peticiones a una API, puedas hacer cualquier tipo de petición ya sea GET, POST, PUT o DELETE.\n### Creando nuestro propio pipe para buscar entre nuestros contactos\nPara crear un pipe personalizado debemos crear un archivo de TypeScript e importar las clases Pipe y PipeTransform desde @angular/core.\n\nimport {Pipe, PipeTransform} from '@angular/core';\n\n@Pipe ({\n  name: 'nombre-del-pipe' // --- este es el nombre con que se implementa en el html\n})\nexport class MiCustomPipe implements PipeTransform {\n  public transform ( value, args: string ) {\n     return \u003cvalor transformado\u003e\n  }\n}\n### Instalando librerías usando npm (bootstrap y font-awesome) y Referenciando CSS en el angular.json\nSe recomienda instalar los paquetes con versiones exactas para evitar incompatibilidades con versiones futuras de las librerías.\n\nnpm install bootstrap --save-exact\nnpm install @fortawesome/fontawesome-free --save-exact\nLuego de instalados los paquetes con npm, la implementación se hace importando las librerías en la sección styles del archivo angular.json\n\n```\n  \"\"styles\"\": [\n    \"\"node_modules/bootstrap/dist/css/bootstrap.css\"\",\n    \"\"node_modules/@fortawesome/fontawesome-free/css/all.css\"\",\n    \"\"src/styles.css\"\"\n  ]\n```\n### Terminando de implementar los estilos de nuestra pantalla de login\nCuando queremos que las clases que estamos definiendo estén disponibles en todo el proyecto y no sólo en la pantalla del componente actual, tendremos que definirlas en el archivo styles.css en la raíz del proyecto y no sólo en el css del componente.\n\n ng serve --open\n\n### Implementando estilos en la pantalla de home\nEn el directorio assets/ del proyecto se encuentran los archivos de imágenes que se usan para los backgrounds en los diferentes contenedores de la UI, así como otras imágenes del proyecto.\n\n### Implementando estilos en home, lista de contactos\nLas clases row y col de Bootstrap permiten distribuir los anchos de los div's de una manera automatizada. En ciertos casos se suelen usar etiquetas de html en lugar de estilos, como es el caso de las etiquetas \u003cb\u003e o \u003ci\u003e.\n\n### Implementando estilos en profile\nCuando usamos inputs de tipo file, normalmente no podemos controlar de manera directa la apariencia en el navegador; incluso, la apariencia de este elemento es muy diferente para los diferentes navegadores. Para evitar esta inconsistencia visual podemos colocar el input dentro de una etiqueta \u003clabel\u003e y ocultarlo con display: none, y aplicar al label una clase para que se ajuste mejor a la apariencia de los botones de nuestra UI.\n\n### ¿Qué es Firebase? Creando nuestro proyecto\nFirebase es un servicio de backend ofrecido por Google de manera gratuita. Provee entre sus utilidades, una base de datos remota más parecida a Mongo que SQL ya que es del tipo no-relacional.\n\nPara implementar este servicio es necesario acceder a la consola de Firebase con una cuenta Google, y seguir las instrucciones de implementación en la sección Base de Datos en Tiempo Real.\n\n\n### Diferencia entre conexión por sockets y HTTP\nConexión HTTP:\n\nSe establece la comunicación al servidor\nSe solicitan los recursos\nSe reciben los recursos\nSe confirman recibidos los recursos\nSe cierra la conexión\nEsto se repite por cada requerimiento de recursos que sean necesarios.\n\nConexión con sockets:\n\nSe establece la comunicación al servidor\nSe solicitan los recursos\nSe reciben los recursos\nSe confirman recibidos los recursos\nLa comunicación queda abierta y escuchando posibles cambios en los recursos\nAl suceder algún cambio en el recurso, el servidor notifica al navegador sin volver abrir nuevas conexiones.\n\n\n### Instalación y setup de la librería AngularFire a través de npm\nPara conectar nuestro proyecto a los servicios de Firebase, usamos AngularFire, disponible en los repositorios de paquetes de npm. Al crear un proyecto en Firebase se nos muestran varias opciones de configuración. La opción de configuración web es la que vamos a utilizar, al obtener los datos y credenciales de autenticación las copiamos en el archivo environment.ts y en environment.prod.ts para que estén disponibles tanto en el ambiente de desarrollo como en producción.\n\nUna vez creadas las variables de configuración será necesario importar los módulos AngularFireModule y environment en app.modules.ts. Finalmente incluímos las clases de Firebase que usaremos en nuestro proyecto en la sección imports: AngularFireAuthModule, AngularFireStorageModule y AngularFireDatabaseModule.\n\n```\nhttps://www.positronx.io/firebase-authentication-in-angular-8-with-angularfire2/\n```\n\n### Guards para verificar Firebase auth\nLos guards son scripts que implementan una estrategia de seguridad para accesos no autorizados a las deferentes rutas de nuestra aplicación. Se crean de manera similar a los servicios y componentes, con el siguiente comando de AngularCLI:\n\nng generate guard \u003cdirectorio\u003e/\u003cnombre-del-guard\u003e\nResultando en la creación de los archivos: \u003cnombre-del-guard\u003e.specs.guard.ts y \u003cnombre-del-guard\u003e.guard.ts\n\nEl guard se basa en un atributo llamado canActivate que, dependiendo de una condición o expresión buleana, retornará verdadero o falso al constructor del componente en el que se haya inyectado para indicarle cuando deberá mostrar o no el contenido de dicho componente.\n\n\n### Perfil de usuario\nPara mostrar la información del usuario en la pantalla de Perfil, necesitamos obtener su uid desde el servicio autenthicationService que creamos antes y usar este uid para extraer los detalles desde la base de datos a través del método getUserById en el servicio de usuario.\n\nUna vez obtenidos los datos adicionales del usuario, los enlazamos a los elementos html del formulario usando NgModel.\n\n### Guardando las imágenes de perfil en nuestra base de datos de firebase\nPara incluir la funcionalidad de agregar foto a nuestro perfil, usaremos el servicio Firebase Storage de Firebase, con AngularFireStorage.\n\nEl servicio FirebaseStorage funciona como un repositorio de recursos estáticos (organizado en carpetas) y se implementa en Angular a través del módulo AngularFireStorageModule, que debemos incluir en app.modules.ts\n\nFinalmente, subiremos la imagen recortada a FirebaseStorage en formato base64, que será convertida por el storage a formato binario. Guardaremos luego en la base de datos, la referencia a la url de esa imagen que obtenemos mediante el método getDownloadURL().\n\n### ¿Cómo resolver el problema de comunicación en tiempo real?\nGeneralmente, en sistemas tradicionales, un cliente envía la información al servidor, donde va a quedar almacenada hasta que otro cliente haga una petición y descargue los datos actualizados a su entorno local. Esto debe hacerlo el cliente dos en intervalos frecuentes que pueden ir desde algunos minutos hasta un segundo o menos, lo que pudiera significar una sobre carga del servidor. Esto va a depender de la cantidad de clientes que realicen peticiones en simultáneo.\n\nFirebase por su parte, usa una estrategia de sockets para manejar las actualizaciones que suceden en su servicio de base de datos en tiempo real. Esto significa que una vez realizada la primera conexión entre la app y el servidor, queda abierto un canal de comunicación permanente entre el servidor y el cliente, y al haber alguna actualización en la base de datos, ésta es notificada al navegador en cuestión de milisegundos, sin necesidad de que éste haya hecho una petición explícitamente, ni sometiendo al servidor a atender peticiones recurrentes en intervalos específicos.\n\nEn nuestra app sólo deberemos tener un método que esté subscrito a los cambios notificados por el servicio de base de datos de firebase a través de un Observable, para actualizar la información de nuestro componente.\n\n\n### Enviando un mensaje (con reproducción de sonido)\nPara el manejo de la conversación en nuestra app, crearemos un servicio llamado conversation, usando el Angular CLI. Usaremos el servicio de base de datos en tiempo real de Firebase a través del objeto AngularFireDatabase inyectado a nuestro servicio en el constructor.\n\nCada mensaje estará identificado con un timestamp del momento en que se generó y una clave única formada por el user.uid de los dos usuarios que intervienen en la conversación, ordenados con sort() y concatenados con join().\n\n### Crear Servicios\nng generate service services/conversation\n\n### createConversation(conversation) {\nreturn this.angularFireDatabase.object(`conversation/${conversation.uid}/${conversation.timestamp}`).set(conversation)\n}\nEnviando un mensaje (con reproducción de sonido)\nPara el manejo de la conversación en nuestra app, crearemos un servicio llamado conversation, usando el Angular CLI. Usaremos el servicio de base de datos en tiempo real de Firebase a través del objeto AngularFireDatabase inyectado a nuestro servicio en el constructor.\n\nCada mensaje estará identificado con un timestamp del momento en que se generó y una clave única formada por el user.uid de los dos usuarios que intervienen en la conversación, ordenados con sort() y concatenados con join().\n\n\n### Enviando un zumbido (con reproducción de sonido y animación)\nEl envío de zumbidos está compuesto de varios aspectos: un mensaje informando que alguien envió un zumbido, la reproducción de un sonido particular y la animación de la pantalla.\nPara esto crearemos un par de métodos nuevos en nuestro servicio conversation, llamados: sendZumbido() y doZumbido().\n\nLa animación será aplicada al elemento del html con la directiva [ngClass] y una clase .shaker que implementa animcaiones de CSS. Esta clase será aplicada al html sólo cuando se cumpla la expresión buleana que indica que el tipo de mensaje es un zumbido.\n\n### Planeación previa para la característica, ¿cómo generaremos las solicitudes?\nPara implementar la característica de solicitudes de amistad usaremos un par de nodos adicionales en la base de datos de Firebase: friends y requests. El nodo friends formará parte de los atributos propios de cada usuario.\n\nLos usuarios sólo podrán comunicarse entre sí sólo cuando se encuentren relacionados como amigos.\n### Aceptando solicitudes de amistad\nGenerando el modal de solicitud de amistad\nPara implementar el modal de solicitud de amistad, usaremos una nueva librería llamada ng2-boostrap-modal.\n\nImportaremos el módulo BoostrapModalModule en el app.component.ts con forRoot() y no en el componente específico de conversation para que el modal pueda ser mostrado en cualquier pantalla de la app en la que estemos y no sólo durante una conversación.\n\nCrearemos un nuevo componente para esta ventana modal utilizando el Angular CLI: ng generate component modals/request, este componente extiende funcionalidades de DialogComponent e implementa PromptModel, que es una interface que tendremos que definir.\n\nFinalmente creamos un nuevo método en el userService llamado addFriend() que insertará en el registro de cada usuario, el user.uid de cada cual, para establecer la relación de amistad entre ellos.\n\n### Mostrando sólo contactos que son amigos\nAceptando solicitudes de amistad\nLas solicitudes de amistad que ha recibido el usuario se obtendrán de la base de datos usando la dirección de correo del usuario actual. Se extraerán los registros del nodo requests y serán guardados localmente en un arreglo; luego, recorriendo este arreglo, se mostrará en el modal la lista de solicitudes pendientes, así el usuario pueda tomar la decisión de aceptarlas, rechazarlas o postergarlas. Para ello usaremos el componente que creamos en la clase anterior: requestsComponent.\n\nEl estatus actualizado se guardará de nuevo en la base de datos.\nt\n### Componentes anidados (con paso de parámetros)\nComo ya vimos en las primeras clases del curso, los componentes en Angular, pueden contener internamente a otros componentes. A éstos se les denomina componentes anidados.\n\nPara poder utilizar información proveniente de un componente externo en uno anidado, es necesario incluir en este último el decorador @Input. Al incluir el nuevo componente en el html del componente padre, deberá pasarse, a través de un atributo colocado entre corchetes “”[ ]\"\", el valor indicado en el decorador @Input.\n\n\n### Creando un wrapper para desktop, usando Electron\nElectron es un framework muy potente que nos permite encapsular nuestras aplicaciones de Angular en wrappers nativos para sistemas operativos de escritorio como Windows, MacOS o Linux. Incluso podremos generar los paquetes de instalación, también nativos, para cada sistema operativo con otra herramienta llamada electron-packager.\n\nElectron debe ser instalado mediante npm:\n\nnpm install electron --save-exact\n# For use in npm scripts (recommended)\n\nnpm install electron-packager --save-dev\nS\n# For use from the CLI\n\nnpm install electron-packager -g\n\nUna vez instalado el paquete, tendremos que crear un archivo llamado main.js en el directorio raíz de nuestra aplicación y referenciarlo en el archivo package.json de nuestra app con el atributo ““main””. En este archivo debemos importar los objetos app y BrowserWindow, además de crear los valores de configuración y la función createWindow(), necesarios para generar la aplicación.\n\nDefinimos los manejadores de los eventos ‘ready’, ‘window-close-all’ y ‘activate’ que enlazarán a la función createWindow() y a las instrucciones necesarias para liberar la memoria de los recursos reservados por la aplicación cuando ésta haya sido cerrada o reactivar si se ha minimizado, respectivamente.\n\nEn el sistema operativo MacOS hay una particularidad, y es que al cerrar la ventana de una aplicación, ésta continúa ejecutándose en segundo plano, por lo que es necesario tener en cuenta esta salvedad en nuestro código para que la aplicación tenga un comportamiento esperado en cada uno de los sistemas operativos.\n\nFinalmente generamos el paquete de producción de nuestra aplicación con el comando de Angular CLI: ng build --prod, generando la carpeta dist/ con los archivos y recursos optimizados y comprimidos para el ambiente de producción y por último el comando electron .\n\nPara generar el paquete de instalación debemos ejecutar:\n\nelectron-packager ./ \u003cnombre-de-la-app\u003e --platform=\u003cplataforma\u003e --icon \u003cubicacion-icono\u003e\nEl parámetro \u003cplataforma\u003e puede tomar los valores: win32 (para SO Windows) o darwin (para MacOS)\n\n```\n npm run electron\nelectron-packager ./ Messenger --platfrom=win32 --icon src/assets/img/logo_live.ico\nelectron-packager ./ Messenger --platfrom=darwin --icon src/assets/img/logo_live.ico\n```\n### Exportando app para web, complementando con Firebase Hosting\nPara hacer el deploy de nuestra app hacia la web, usaremos el servicio de hosting gratuito de Firebase, para lo cual sólo es necesario seguir los siguientes pasos:\n\nInstalar las Firebase tools con npm install -g firebase-tools\nHacer login desde la terminal con firebase login\nInicializar el directorio del proyecto con firebase init\ny realizar el despliege con firebase deploy\nAl finalizar el proceso de deploy, Firebase nos indicará la url en la que se ha hecho la publicación. Esta url será servida de manera segura a través de https por Firebase.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevdevi%2Fangular-6","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevdevi%2Fangular-6","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevdevi%2Fangular-6/lists"}