2.2 - Mi primera App

Hay dos formas de trabajar sobre Angular, una es usar el CLI y la otra es traer todo a mano ( como veniamos acostumbrados anteriormente ), la verdad que ambas tienen sus beneficios y contras (como todo en la vida del desarrollador) pero vamos a ver ambas opciones y luego nos vamos a quedar por una hibrida.

SystemJS

La primer opción como comente seria una opcion "manual" por lo tanto deberiamos traer todo a mano y arrancar Angular con SystemJS.

Basandonos en el siguiente enlace de la documentacion oficial (https://embed.plnkr.co/?show=preview&show=app%2Fapp.component.ts\) vamos a ver como seria un Hello Angular.

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Hello Angular</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
      body {color:#369;font-family: Arial,Helvetica,sans-serif;}
    </style>

    <!-- Polyfills for older browsers -->
    <script src="https://unpkg.com/core-js/client/shim.min.js"></script>

    <script src="https://unpkg.com/zone.js@0.7.4?main=browser"></script>
    <script src="https://unpkg.com/reflect-metadata@0.1.8"></script>
    <script src="https://unpkg.com/systemjs@0.19.39/dist/system.src.js"></script>

    <script> window.autoBootstrap = true; </script>

    <script src="https://cdn.rawgit.com/angular/angular.io/b3c65a9/public/docs/_examples/_boilerplate/systemjs.config.web.js"></script>
    <script>
      System.import('app').catch(function(err){ console.error(err); });
    </script>
  </head>

  <body>
    <my-app>Loading AppComponent content here ...</my-app>
  </body>

</html>


<!-- 
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
-->

En nuestro index.html deberiamos poner todo esto... de esta forma traeriamos todos los JS necesarios para poder hacer nuestro primer "Hello Angular"...

Viendo un opco mas en detalle, traemos Shim, Zone, Reflect, systemjs y angular (la version que se hizo para el plnkr)...

Luego de eso ejecutamos SystemJS, para cargar la "app" ...

Y podemos observar que en el body tenemos un Componente llamado "my-app", el cual no recibe ningun tipo de parametro, pero si tiene texto adentro, si no lo adivinaste todavia, este texto esta simplemente para que la web muestre algo mientras se esta cargando el contenido del componente, para que este cargue primero tiene que traer todas las dependencias que pusimos para que traiga la pagina y ahi pueda ejecutar SystemJS a Angular... pero esto no es todo...

app/app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `<h1>Hello {{name}}</h1>`
})
export class AppComponent { name = 'Angular'; }


/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/

Esta era la parte que nos falto, hasta ahora solo vimos ejemplos de componentes en su parte de HTML, pero no habiamos visto la parte que los define, que les da funcionalidad, quien muestra su estructura HTML, o quien le da la funcionalidad, o simplemente quien genera todo el componente.

Vamos a ver "muy por arriba" que es este TS ( typescript).

Si nunca viste typescript, y venis de programar en algun lenguaje tipado y orientado a objetos, vas a sentir sienta comodidad... Si claro, estas viendo un import un annotation, una clase, esto parece algun tipo de magia oscura, pero no lo es.

Si venis del frontend todo esto puede llegar a hacerte mucho ruido, ya que JS me dejaba hacer lo que queria, aca veo cosas raras, no te preocupes, vamos a ver todo ...

Pero volviendo al ejemplo, este TS, importa "algo", que casualmente se llama componente, lo que quiere decir es que va a traer de "angular => core" la funcionalidad de componente.

Lo que se ve con un "@" (arroba) es un decorador (que es el componente) que lo que va a hacer en un modo simple de definir, es una serie de metadata para el navegador... Como por ejemplo como se llama el tag del componente, que es el selector (en nuestro caso serial <my-app> pero al annotation solo le tenemos que pasar el contenido no los < > ) , como asi le damos un template osea una "pedazo" de HTML para que tenga una estructura web... y luego exporta una clase que simplemente crea una variable del nombre "name" y le asigna el valor "Angular"...

Muy bien, ya te diste cuenta no? El " { { } } " ( si doble llave, que lo podriamos llamar de muchas formas, para nosotros va a ser doble llave) es lo que une el HTML o Template con la Clase... por lo tanto, cuando escribimos en nuestro template _ _lo que va a hacer Angular es buscar una variable en la clase correspondiente con el mismo nombre (respetando mayusculas y minusculas ) y unir el contenido de la variable con la vista del template.

Hasta ahi parece todo bastante facil para arrancar... pero la verdad que en este ejemplo tenemos servido algo que luego de un tiempo y de necesidad de agrandar las funcionalidades de nuestra WEBAPP vamos a tener que modificar y ahi es donde se vuelve mas complicado utilizar y es el archivo de configuracion de SystemJS.

systemjs.config.web.js

Este que tenemos nostros en el ejemplo es uno hecho y dedicado para el ejemplo inicial de angular el cual nos serviria de base para arrancar un proyecto.

/**
 * WEB ANGULAR VERSION
 * (based on systemjs.config.js in angular.io)
 * System configuration for Angular samples
 * Adjust as necessary for your application needs.
 */
(function (global) {
  System.config({
    // DEMO ONLY! REAL CODE SHOULD NOT TRANSPILE IN THE BROWSER
    transpiler: 'ts',
    typescriptOptions: {
      // Copy of compiler options in standard tsconfig.json
      "target": "es5",
      "module": "commonjs",
      "moduleResolution": "node",
      "sourceMap": true,
      "emitDecoratorMetadata": true,
      "experimentalDecorators": true,
      "noImplicitAny": true,
      "suppressImplicitAnyIndexErrors": true
    },
    meta: {
      'typescript': {
        "exports": "ts"
      }
    },
    paths: {
      // paths serve as alias
      'npm:': 'https://unpkg.com/'
    },
    // map tells the System loader where to look for things
    map: {
      // our app is within the app folder
      app: 'app',

      // angular bundles
      '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
      '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
      '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
      '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
      '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
      '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
      '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
      '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
      '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js',
      '@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js',

      // other libraries
      'rxjs':                      'npm:rxjs',
      'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js',
      'ts':                        'npm:plugin-typescript@4.0.10/lib/plugin.js',
      'typescript':                'npm:typescript@2.0.3/lib/typescript.js',

    },
    // packages tells the System loader how to load when no filename and/or no extension
    packages: {
      app: {
        main: './main.ts',
        defaultExtension: 'ts'
      },
      rxjs: {
        defaultExtension: 'js'
      }
    }
  });

  if (global.autoBootstrap) { bootstrap(); }

  // Bootstrap with a default `AppModule`
  // ignore an `app/app.module.ts` and `app/main.ts`, even if present
  // This function exists primarily (exclusively?) for the QuickStart
  function bootstrap() {
    console.log('Auto-bootstrapping');

    // Stub out `app/main.ts` so System.import('app') doesn't fail if called in the index.html
    System.set(System.normalizeSync('app/main.ts'), System.newModule({ }));

    // bootstrap and launch the app (equivalent to standard main.ts)
    Promise.all([
      System.import('@angular/platform-browser-dynamic'),
      getAppModule()
    ])
    .then(function (imports) {
      var platform = imports[0];
      var app      = imports[1];
      platform.platformBrowserDynamic().bootstrapModule(app.AppModule);
    })
    .catch(function(err){ console.error(err); });
  }

  // Make the default AppModule
  // returns a promise for the AppModule
  function getAppModule() {
    console.log('Making a bare-bones, default AppModule');

    return Promise.all([
      System.import('@angular/core'),
      System.import('@angular/platform-browser'),
      System.import('app/app.component')
    ])
    .then(function (imports) {

      var core    = imports[0];
      var browser = imports[1];
      var appComp = imports[2].AppComponent;

      var AppModule = function() {}

      AppModule.annotations = [
        new core.NgModule({
          imports:      [ browser.BrowserModule ],
          declarations: [ appComp ],
          bootstrap:    [ appComp ]
        })
      ]
      return {AppModule: AppModule};
    })
  }
})(this);

/*
Copyright 2016 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/

WOW, si es un poco mas grande de lo que esperabamos, pero simplemente yo quiero utilizar el framework no quiero tener que estar configurando mil cosas, para eso vamos a tener el CLI.

_Advertencia: _este archivo de configuracion (systemjs.config.web.js) no lo deberiamos utilizar tal y como esta, ya que esta transpilando momento de ejecución

AngularCLI

No es nada nuevo que un framework tenga un CLI hoy en dia para los que trabajamos en frontend o mejor dicho con JS a lo largo de los utlimos años, es algo que se esta volviendo comun y esta bueno para algunas cosas y para otras no... Desde el AngularCLI, a partir de ahora CLI, nosotros podriamos tranquilamente hacer toda la app, desde crearla, agregar funcionalidades base, arquitectura de archivos, ejecutar los test, ejecutar un servidor de prueba local, hasta hacer el build final sin tener que CREAR una carpeta o archivo dentro del proyecto a "mano", ya sea apretando click derecho en nuestro navegador de carpetas o desde nuestro editor de texto.

Pero despues de tiempo de utilizarlo, realmente creo que una opción intermedia es lo mejor que podemos utilizar... para eso primero vamos por la opción 100% CLI.

Para instalar el CLI ( Documentación oficial => http://cli.angular.io/ ), vamos a tener que abrir nuestra consola e hacer lo siguiente (entendiendo que tienen NodeJS instaldo ya, si no lo tenes entra a http://www.nodejs.org/es/ y descargalo)

npm install -g angular-cli

Una vez que termine vamos a poder empezar a crear proyectos directamente desde nuestra terminal, para eso vamos a tener que ejecutar el siguiente comando.

ng new NombreProyecto

este por defecto nos va a crear un proyecto desde cero en Typescript, en el caso de no queres utilizar TypeScript (si no le diste una oportunidad es hora que lo hagas) vas a tener que utilizar inputs para que traiga el template incial de JavaScript o de Dart.

Volviendo al comando vamos a tener la misma solución una vez que arranquemos nuestro localhost...

ng serve

que va a hacer ? A simple modo, lo que va a hacer es levantarnos un servidor web liviano y mostrarnos el resultado de nuestra WEBAPP aunque no hicimos nada todavia...

Si, la preview es la misma, es el mismo resultado pero mucho mas rapido todavia!

Last updated