shoppingcart - keblato/TutorialesTalleres-Angular GitHub Wiki
Ejemplo ShoppingCart
Este ejemplo es una adaptación del que se encuentra aquí.
Vamos a desarrollar el ejemplo del Shopping Cart en Angular. Los requerimientos:
- Se debe poder crear ítems de compra con descripción, cantidad y costo
- Se debe incluir el subtotal de cada ítem.
- Se debe totalizar toda la lista del Shopping Cart
- Se debe poder borrar un ítem de compra.
Stackblitz
El código de este ejemplo está en: | https://stackblitz.com/edit/shoppingcart-isis |
---|
Para poder modificar el ejercicio, cree una cuenta en Stackblitz, y haga click en "Fork". De esta forma, podrá guardar los cambios que realice al resolver los desafíos.
Diseño de la Interfaz
Primero definimos un prototipo de cómo debería verse la aplicación:
Figura 1: Interfaz usuario applicación shopping cart |
Diseño de la aplicación
Por ser esta una aplicación simple, vamos a definir un módulo principal y el componente de ShoppingCart. El siguiente diagrama muestra la decisión de diseño.
![]() |
---|
Figura 2: Diagrama de clases de la applicación shopping cart |
Como se puede ver, tenemos el módulo principal AppModule
con su componente por defecto AppComponent
. Tenemos un componente adicional ShoppingCartComponent
que tiene el modelo del shopping cart, llamado invoice
, y, dado lo simple de la lógica, la hemos definido directamente como métodos del componente.
Vale la pena mencionar que siempre que hablamos de un componente, estamos incluyendo al menos 4 elementos:
- La clase componente que es la que se muestra en el diagrama,
- La vista del componente (el Html),
- Los estilos que se le aplicarán a la vista y
- La especificación de las pruebas.
También, en el diagrama estamos mostrando un comentario asociado con cada componente que incluye "decoraciones" o metadatos que serán utilizados por Angular cuando despliegue la aplicación. En el caso del componente estos son: el selector que se refiere al tag de html que se crea para que cuando se utilice dentro de un html allí se despliegue el componente y el nombre del archivo que contiene la definición de la vista del componente.
Estructura del proyecto
Este proyecto sigue una estructura estándar de proyectos Angular. Dentro de la carpeta app
están los módulos (en este caso sólo uno) y los componentes. El componente shopping-cart está dentro de su propia carpeta. En la siguiente figura, los archivos que están encerrados en el cuadro verde corresponden al componente ShoppingCartComponent
.
Figura 3: Estructura de archivos de la applicación shopping cart |
Note que hay un archivo llamado item.model.ts , contiene la definición de la clase item . |
El archivo que está abierto index.html
utiliza el selector
o tag html que fue definido en el AppComponent
, ver Figura 2, es decir my-app
. Allí tambien hay otro meta-dato llamado templateUrl
cuyo valor es el nombre del archivo html de la vista del componente ShoppingCartComponent
. Esto significa que cuando se encuentre el tag my-app
este se remplazará por la vista del componente.
Este template se muestra en la siguiente figura:
Figura 4: Template o vista del componente ShoppingCartComponent |
El html anterior utiliza:
- Estilos de bootstrap +4.1 que fueron importados en el archivo
stype.css
que se encuentra en la raíz del proyecto. - Evaluación de expresiones
{{ ..| ..}}
. Tiene dos partes, la expresión que se evaluará y el formato en el que se desplegará la respuesta. Por ejemplo, en la línea 27 se invoca la funcionsubtotal
y la respuesta se formatea como una moneda. - Marcado de Angular como por ejemplo
[(ngModel)]
esta directiva significa un "two-way binding"; cuando el campo es actualizado desde la vista, por ejemplo por el usuario, la variable también toma ese valor. Si la variable es actualizada desde el código, el campo en la vista también es actualizado.
Este comportamiento se puede apreciar si ud. cambia los valore sobre la forma de la cuenta del carritos. Este cambio queda reflejado en la variable invoice
.
Figura 5: "two-way binding" |
ShoppingCartComponent
Descripción del componente El componente inicia importando el modelo de un item
.
La razón por la que se utilizan los modelos es para lograr que su definición y tratamiento (En este caso del item
) sean los mismos en toda la aplicación. Las ventajas de esto son más claras en una aplicación más grande, pero imagine que va a agregar un nuevo componente para manejar las facturas.
Si no existiera el modelo, el código perdería claridad con respecto a qué es un item en cada uno de los componentes. Esto se tendría que definir en cada uno de ellos, o en el peor de los casos en ninguno, y las modificaciones podrían por ejemplo no replicarse.
El constructor del componente inicializa la factura como una lista vacía, y le agrega un nuevo item utilizando el modelo.
![]() |
---|
Figura 6: "Estructura básica del componente" |
Con respecto a las operaciones del ShoppingCart, para este ejemplo de introducción, se ha decidido implementarlas dentro del componente.
El componente cuenta con 4 métodos:
addItem
que agrega un nuevo item a la facturadeleteItem
que elimina el item que recibe por parámetro de la facturasubTotal
que calcula y mantiene actualizada la variable del subtotal de cada item (su precio * su cantidad)total
que calcula y mantiene actualizado el valor de la factura
![]() |
---|
Figura 7: "Métodos del componente" |
Desafíos
- Modifique el componente
ShoppingCartComponent
para que al inicializar, el producto que agregue tenga un valor de99,95
. - Agregue al modelo
item
el atributotype
que puede ser de 3 tipos:meat
,beverage
ofruit
. Haga las modificaciones necesarias para agregar esta columna a la tabla del shopping cart. El campo debe ser de tiposelect
. - Utilizando los estilos de Bootstrap 4.1, cambie los botones para que sean de tipo "Outline button" y haga una modificación adicional de su preferencia para personalizarlos (ej. tamaño, fuente, etc.)
- Es usual en la estructura de los proyectos Angular que la lógica de los componentes se defina en un servicio. Cambie a un servicio(@Injectable) la lógica del componente
ShopingCartComponent
. Es decir, todas aquellas operaciones cuya responsabilidad difiera de interactuar con la vista. El componente debe inyectar un servicio y hacer llamados a este para recibir el resultado de las operaciones.