Ionic es un popular framework front-end JavaScript para desarrollar aplicaciones móviles multiplataforma usando Apache Cordova . El Marco Iónico da a las aplicaciones Cordova una apariencia nativa y ajusta automáticamente esa apariencia a través de las plataformas. Puede utilizar Visual Studio 2017 y Visual Studio Tools para Apache Cordova (TACO) para crear y depurar fácilmente aplicaciones multiplataforma Ionic.
En este artículo, vermos como configurar un entorno de desarrollo de Visual Studio 2017 para Ionic 2 y crear una versión Ionic 2 de la aplicación Weather que se muestra a continuación:
Requisitos
Para administrar, codificar, ejecutar y depurar aplicaciones Ionic 2 utilizando Visual Studio, debe instalar lo siguiente:
- Visual Studio 2017
- Herramientas de Visual Studio para Apache Cordova
- Plantillas de Visual Studio Ionic 2
- Dependencias de plantillas Ionic 2 (descritas a continuación)
Instalación de las plantillas de Ionic 2
- Si aún no lo ha hecho, instale Visual Studio 2017 y TACO. Bajo las portadas, las aplicaciones de Ionic son aplicaciones de Apache Cordova, necesitará un entorno de desarrollo de Cordova funcional antes de poder desarrollar aplicaciones usando Ionic. Compruebe que puede crear y ejecutar la aplicación predeterminada Presione Cordova Blank . El navegador Chrome debe abrir y mostrar el contenido de la aplicación. F5 para crear y ejecutar el nuevo proyecto utilizando la nueva opción Simular en explorador .
- Instale la plantilla de Ionic en Visual Studio seleccionando el menú En el cuadro de diálogo Extensiones y actualizaciones, seleccione En el cuadro de búsqueda situado en la esquina superior derecha del cuadro de diálogo, escriba Seleccione la opción Haga clic en el botón Cuando se le solicite, haga clic en el botón Herramientas , luego Online . Ionic 2 . Ionic 2 Templates en la lista. Descargar para iniciar la instalación. Extensiones y actualizaciones .... Los archivos de plantilla se descargarán, a continuación, Visual Studio iniciará automáticamente el proceso de instalación. Instalar para comenzar la instalación.
Creación de un proyecto Ionic en Visual Studio
- Crear un nuevo proyecto Ionic. En el cuadro de diálogo del nuevo proyecto, expanda la sección de plantillas de Esto es un proyecto simple, así que selecciona la plantilla en TypeScript y, a continuación, seleccione Apache Cordova Apps . blanco .
- Compruebe el archivo Readme del nuevo proyecto de Ionic para cualquier herramienta adicional que se debe instalar para utilizar la plantilla. En el momento de escribir este documento, solo necesitará instalar la extensión NPM Task Runner .
Los requisitos pueden cambiar a medida que se realizan actualizaciones a las plantillas. Para instalar las extensiones necesarias, abra el menú Herramientasy seleccione Extensiones y actualizaciones . Utilice la búsqueda para localizar e instalar las extensiones requeridas.
- Ionic es un marco pesado, que requiere una gran cantidad de herramientas y bibliotecas para operar. Una vez que Visual Studio crea el nuevo proyecto, inicia un proceso para descargar e instalar los componentes necesarios mediante Node Package Manager (npm). Espere unos minutos mientras se instalan los paquetes ncm de Ionic.
Nota : Este proceso tomará varios minutos dependiendo del sistema y las velocidades de conexión a Internet.
Para comprobar el progreso, abra el Debería ver Explorador de soluciones y busque el nodo Restaurar ... si no lo hace, expanda el nodo Dependencias en el Administrador de soluciones y, a continuación, haga clic con el botón derecho en la carpeta npm y seleccione Restaurar paquetes . Dependencias .
Puede supervisar el proceso de instalación del paquete a través de la ventana de resultados de Visual Studio. Abra el menú Ver , luego seleccione Salida o utilice el método abreviado de teclado Ctrl-W + O :
- En este punto, usted tiene un proyecto de aplicación Ionic completo listo para funcionar. El desarrollo de aplicaciones iOS requiere alguna configuración adicional;
Creación de la aplicación de tiempo
Ahora, vamos a hacer algo con esta aplicación que creaste. Usted tomará el proyecto de aplicación en blanco y lo convertirá en la aplicación de tiempo mostrada anteriormente. En las siguientes secciones, comenzará agregando una página de Empecemos. Condiciones actuales , luego conectará en un cuadro de búsqueda y, finalmente, agregará un área para mostrar los datos de pronóstico .
La aplicación utiliza el servicio gratuito OpenWeatherMap para recuperar las condiciones meteorológicas de una ubicación. Antes de poder utilizar el servicio, debe configurar una cuenta y solicitar una clave de API para su API Condiciones actuales. Apunte su navegador a OpenWeatherMap y configure una cuenta. Una vez que tenga un inicio de sesión válido, vaya a la página API del servicio y suscríbase al servicio de datos Tiempo actual y, a continuación, genere una clave de API.
Configuración del proyecto de aplicación
- Comience configurando algunas opciones de configuración para la aplicación. En Visual Studio Solution Explorer, haga doble clic en el archivo Puede que también desee actualizar los campos
config.xml
del proyecto. Visual Studio abrirá un editor personalizado como el que se muestra en la siguiente figura: Autory Descripción . - De forma predeterminada, la aplicación muestra datos meteorológicos basados en la ubicación actual del dispositivo, por lo que necesitaremos utilizar el complementoCambie a la pestaña Haga clic en el botón Cordova Geolocation para añadir esta capacidad a nuestra aplicación. Puede utilizar las capacidades de geolocalización incorporadas del navegador, pero Cordova y Ionic proporcionan capacidades especiales que hacen que el uso de la geolocalización en una aplicación de Ionic sea un poco más fácil. Plugins del editor y seleccione el complemento Geolocation en la lista. Agregar para agregar el complemento al proyecto.
Presione la tecla Ctrl + S del teclado para guardar sus cambios, luego cierre el archivo del editor.
- Abra el archivo
src\index.html
del proyecto y cambie el título de la aplicación. Esto no es un paso obligatorio, pero si más tarde prueba la aplicación en el navegador, el título de la aplicación será correcto.<title>Weather App Ionic</title>
Generación de un proveedor de tiempo
Ahora, vamos a empezar a trabajar en el código de la aplicación. Por convención, las aplicaciones iónicas segregan fuentes de datos de otros tipos de código de aplicación utilizando un tipo de componente Dado que los datos meteorológicos provienen de una fuente externa y no queremos que el código de la aplicación llame directamente al servicio, haremos un proveedor de Proveedores especial. tiempo y pondremos allí todo el código de acceso a la aplicación.
- En el Explorador de soluciones, haga clic con el botón secundario en la carpeta Asigne un nombre a los
src
del proyecto y seleccioneproviders
carpetas y presione la tecla Intro . Agregar -> Nueva carpeta . Esto crea una carpeta para todos los proveedores que usará la aplicación (solo tendremos una, pero muchas aplicaciones de Ionic tendrán varias). - Haga clic con el botón derecho en la nueva carpeta de En el cuadro de diálogo que aparece, seleccione La CLI Iónica creará el proveedor en
providers
y seleccione Ionic 2 Provider y, en el campo Name , escribasrc\providers\Weather.ts
Weather
. Agregar -> Nuevo elemento . - Ahora que usted tiene el proveedor de Abra el archivo
Weather
, usted tiene que decir Ionic sobre él.src\app\app.module.ts
del proyecto y agregue la línea siguiente a la sección de importaciones en la parte superior del archivo:import { WeatherProvider } from '../providers/weather';
- A continuación, agregue una referencia al proveedor de clima en la matriz de
providers
del archivo:providers: [WeatherProvider, {provide: ErrorHandler, useClass: IonicErrorHandler}]
Guarde los cambios antes de continuar.
Codificación del proveedor de tiempo
En esta sección, agregaremos código al Proveedor de tiempo para conectarse con la API meteorológica externa y entregar datos a la aplicación.
- Abra el archivo
src\providers\Weather.ts
recién creado y modifique la importación@angular/http
en la parte superior del archivo para que se vea como sigue:import { Http, Response } from [email protected]/http';
El componente HTTP se carga por defecto en cualquier proveedor, lo que está haciendo aquí es añadir el componente de respuesta que usaremos en el código del proveedor más adelante.
- Aún en la parte superior del archivo, agregue una importación que cargue el módulo
toPromise
:import 'rxjs/add/operator/toPromise';
Cuando haya terminado, la sección de importaciones en la parte superior del archivo se verá así:
import { Injectable } from [email protected]/core'; import { Http, Response } from [email protected]/http'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/toPromise';
- En la parte superior de la clase
Weather
, agregue las siguientes declaraciones de variables:private weatherEndpoint = 'http://api.openweathermap.org/data/2.5/'; private weatherKey = '';
weatherKey
variableweatherKey
con la clave API que obtuvo anteriormente del servicio meteorológico. - Después del constructor de la clase de
weather
, agregue el código siguiente:getCurrent(loc: any): Promise<any> { let url: string = this.makeDataURL(loc, 'weather'); return this.http.get(url) .toPromise() .then(this.extractData) .catch(this.handleError); } private makeDataURL(loc: any, command: string): string { //Build a weather service URL using the command string and //location data that we have. let uri = this.weatherEndpoint + command; //Do we have a location? if (loc.long) { //then use the 'grographical coordinates' version of the API uri += '?lat=' + loc.lat + '&lon=' + loc.long; } else { //Otherwise, use the zip code uri += '?zip=' + loc.zip; } //Configure output for imperial (English) measurements uri += '&units=imperial'; //Use the following instead for metric //uri += '&units=metric'; //Append the API Key to the end of the URI uri += '&APPID=' + this.weatherKey; //Return the value return uri; } //'Borrowed' from //https://angular.io/docs/ts/latest/guide/server-communication.html private extractData(res: Response) { //Convert the response to JSON format let body = res.json(); //Return the data (or nothing) return body || {}; } //'Borrowed' from //https://angular.io/docs/ts/latest/guide/server-communication.html private handleError(res: Response | any) { console.error('Entering handleError'); console.dir(res); return Promise.reject(res.message || res); }
Al iniciar, la aplicación pasa la ubicación actual (longitud y latitud) a la función
getCurrent
. Al buscar una ubicación utilizando un código postal de Estados Unidos, se pasa el código postal en su lugar.getCurrent
llama a la API apropiada para obtener los datos meteorológicos actuales, pero usamakeDataURL
para dar formato a la URL de la solicitud correctamente dependiendo de si tiene una ubicación o un valor de código postal.La función Este código podría ser fácilmente incluido directamente en el método
extractData
formatea los datos devueltos por la llamada API como JSON.getCurrent
, pero como verás más adelante, este código se utiliza más de una vez por la aplicación, por lo que tenía sentido para mover una función separada.
Crear la página Condiciones actuales
- Abra el archivo
src\pages\home\home.html
y reemplace el contenido del archivo por lo siguiente:<ion-header> <ion-toolbar> <ion-buttons right> <button ion-button (click)="refreshPage()"> <ion-icon name="refresh"></ion-icon> </button> </ion-buttons> <ion-title> Weather App (Ionic 2) </ion-title> </ion-toolbar> </ion-header> <ion-content padding> <ion-list no-lines> <!--show this if there are no items in the list--> <ion-item [hidden]="c_items.length > 0"> <p><strong>Weather data is not available</strong></p> </ion-item> <!--Display the current conditions data we have --> <ion-item *ngFor="let c_item of c_items"> <p><strong>{{c_item.name}}:</strong> {{c_item.value}}</p> </ion-item> </ion-list> </ion-content> <ion-footer> <ion-toolbar> <ion-title>Visual Studio Tools for Apache Cordova</ion-title> </ion-toolbar> </ion-footer>
Lo que se ve en el archivo es referencias a componentes iónicos, así como algunos códigos Angulares también. Este marcado es un subconjunto del HTML de la página, el resto se encuentra en los archivos En la puesta en marcha, el marco iónico reemplaza el contenido de la etiqueta En este caso, cuando la aplicación se inicia, el contenido de la página
src\index.html
ysrc\app\app.html
.<ion-app></ion-app>
del archivosrc\pages\home\home.html
se analiza y procesa.src\index.html
archivosrc\app\app.html
<ion-nav [root]="rootPage"></ion-nav>
continuación, pasa contenido HTML dentro y fuera de esa etiqueta como el usuario utiliza la aplicación.El encabezado contiene una barra de herramientas que muestra el título de la aplicación y un botón de actualización que el usuario puede tocar para actualizar los datos meteorológicos que se muestran en la página.
La etiqueta de En este ejemplo, muestra una En este caso, procesa el contenido de la matriz A medida que el código loops, asigna cada elemento de la matriz a Verá cómo la matriz
ion-content
define la parte del contenido que comprende el contenido dinámico de la página.<ion-list>
de elementos; Básicamente un listview.c_items
como una lista usando una directiva Angular:*ngFor="let c_item of c_items"
que sec_item
, entonces el código de plantilla que sigue muestra las propiedades dec_items
se rellenará pronto.name
yvalue
del objetoc_item
.*ngFor="let c_item of c_items"
través de cada elemento de la matriz. - Abra el archivo
src\pages\home\home.ts
del proyecto. En la parte superior del archivo, añada las importaciones para el complemento Geolocalización y el proveedor de clima:import { Geolocation, Keyboard } from 'ionic-native'; import { WeatherProvider } from '../../providers/weather';
- También en la parte superior del archivo, modifique la importación
ionic-angular
por lo que se ve así:import { AlertController, LoadingController, NavController, Platform } from 'ionic-angular';
Esto carga algunos componentes adicionales usados por el código de la página:
AlertController
gestiona la visualización de diálogos de alerta.LoadingController
gestiona la visualización de una hiladora de carga.NavController
gestiona la navegación entre las páginas.Platform
proporciona utilidades relacionadas con la plataforma.
- Dentro de la clase
HomePage
, agregue las siguientes declaraciones de variables:degreeStr: string = ' degrees (F)'; //an empty object (for now) to store our location data passed to the API currentLoc: any = {}; //current weather items array c_items: Array<any> = [];
- Agregue los siguientes parámetros al constructor de clase
HomePage
:public alertController: AlertController, public loadingCtrl: LoadingController, public platform: Platform, public weather: WeatherProvider,
Cuando haya terminado, debería verse así:
constructor( public alertController: AlertController, public loadingCtrl: LoadingController, public nav: NavController, public platform: Platform, public weather: WeatherProvider ) { }
- Reemplace la función
openLink
en el cuerpo de la claseHomePage
con lo siguiente (la funciónopenLink
es parte de la plantilla en blanco iónica y no es utilizada por la aplicación Weather):ionViewDidLoad() { //Once the main view loads //and after the platform is ready... this.platform.ready().then(() => { //Setup a resume event listener document.addEventListener('resume', () => { //Get the local weather when the app resumes this.getLocalWeather(); }); //Populate the form with the current location data this.getLocalWeather(); }); } refreshPage() { this.showCurrent(); } getLocalWeather() { let locOptions = { 'maximumAge': 3000, 'timeout': 5000, 'enableHighAccuracy': true }; Geolocation.getCurrentPosition(locOptions).then(pos => { //Store our location object for later use this.currentLoc = { 'lat': pos.coords.latitude, 'long': pos.coords.longitude }; //and ask for the weather for the current location this.showCurrent(); }).catch(e => { console.error('Unable to determine current location'); if (e) { console.log('%s: %s', e.code, e.message); console.dir(e); } }) } showCurrent() { //clear out the previous array contents this.c_items = []; //Create the loading indicator let loader = this.loadingCtrl.create({ content: "Retrieving current conditions..." }); //Show the loading indicator loader.present(); this.weather.getCurrent(this.currentLoc).then( data => { //Hide the loading indicator loader.dismiss(); //Now, populate the array with data from the weather service if (data) { //We have data, so lets do something with it this.c_items = this.formatWeatherData(data); } else { //This really should never happen console.error('Error retrieving weather data: Data object is empty'); } }, error => { //Hide the loading indicator loader.dismiss(); console.error('Error retrieving weather data'); console.dir(error); this.showAlert(error); } ); } private formatWeatherData(data): any { //create a blank array to hold our results let tmpArray = []; //Add the weather data values to the array if (data.name) { //Location name will only be available for current conditions tmpArray.push({ 'name': 'Location', 'value': data.name }); } tmpArray.push({ 'name': 'Temperature', 'value': data.main.temp + this.degreeStr }); tmpArray.push({ 'name': 'Low', 'value': data.main.temp_min + this.degreeStr }); tmpArray.push({ 'name': 'High', 'value': data.main.temp_max + this.degreeStr }); tmpArray.push({ 'name': 'Humidity', 'value': data.main.humidity + '%' }); tmpArray.push({ 'name': 'Pressure', 'value': data.main.pressure + ' hPa' }); tmpArray.push({ 'name': 'Wind', 'value': data.wind.speed + ' mph' }); //Do we have visibility data? if (data.visibility) { tmpArray.push({ 'name': 'Visibility', 'value': data.visibility + ' meters' }); } //do we have sunrise/sunset data? if (data.sys.sunrise) { var sunriseDate = new Date(data.sys.sunrise * 1000); tmpArray.push({ 'name': 'Sunrise', 'value': sunriseDate.toLocaleTimeString() }); } if (data.sys.sunset) { var sunsetDate = new Date(data.sys.sunset * 1000); tmpArray.push({ 'name': 'Sunset', 'value': sunsetDate.toLocaleTimeString() }); } //Do we have a coordinates object? only if we passed it in on startup if (data.coord) { //Then grab long and lat tmpArray.push({ 'name': 'Latitude', 'value': data.coord.lat }); tmpArray.push({ 'name': 'Longitude', 'value': data.coord.lon }); } //Return the new array to the calling function return tmpArray; } showAlert(message: string) { let alert = this.alertController.create({ title: 'Error', subTitle: 'Source: Weather Service', message: message, buttons: [{ text: 'Sorry' }] }); alert.present(); }
Hay un montón de código allí; Tomar unos minutos y estudiarlo. Esto es lo que hace:
- En este caso, la función llama a la función Utiliza las capacidades del componente
ionViewDidLoad
:getLocalWeather
para iniciar el proceso de obtención de datos meteorológicos para la ubicación actual del dispositivo. Platform para asegurarse de que no hace nada hasta que es seguro que el contenedor de aplicación nativo y el marco Ionic han finalizado la inicialización.ionViewDidLoad
un evento que seionViewDidLoad
cuando la página finaliza la carga. refreshPage
: se ejecuta cuando el usuario de la aplicación hace clic en el botón Actualizar de la barra de herramientas. Aquí, actualiza los datos meteorológicos actuales en la página. Esta función obtiene más responsabilidades más adelante.getLocalWeather
- Determina la ubicación actual del dispositivo (usando el complemento Cordova Geolocation), luego llama ashowCurrent
para obtener los datos meteorológicos actuales.showCurrent
- Muestra el indicador de carga y luego llama al proveedor de tiempo para obtener datos meteorológicos para la ubicación especificada (ya sea una geolocalización o, posteriormente, un código postal).formatWeatherData
- Los resultados que obtiene la aplicación de la API meteorológica dependen de si la aplicación solicita las condiciones actuales o la previsión. No estamos pidiendo datos de pronóstico (todavía) pero, pero más tarde. Esta función construye un objeto de datos meteorológicos a partir de los resultados y tiene un código especial que construye el objeto apropiado en función de si se trata de condiciones actuales o de un pronóstico.showAlert
: muestra un cuadro de diálogo de error si se rompe algo.
- En este caso, la función llama a la función Utiliza las capacidades del componente
Ejecute la aplicación en el navegador, un emulador, un simulador o un dispositivo físico conectado al ordenador. Si ejecuta la aplicación en el navegador, utilizando las capacidades de Cordova Simulate de Visual Studio 2017, puede ajustar las coordenadas del dispositivo simulado mediante el panel Geolocation; Cuando se cargue la aplicación, se le solicitará que autorice el acceso de la aplicación a la ubicación actual del dispositivo, como se muestra a continuación:
Cuando permite el acceso (no toque negar , ya que no podrá hacer mucho con la aplicación si lo hace), debería ver los datos meteorológicos actuales de la ubicación actual como se muestra en la siguiente figura:
No es la aplicación completa de interfaz de usuario, pero al menos se pueden ver los resultados del tiempo. En la siguiente sección, agregamos el cuadro de búsqueda de código postal para que pueda obtener datos meteorológicos para una ubicación específica.
Adición de búsqueda de código postal
Es útil disponer de datos meteorológicos para la ubicación actual, pero ¿qué pasa si viajas a algún lugar y quieres saber cómo será el tiempo cuando llegues? En esta sección, agregará un cuadro de búsqueda que los usuarios pueden utilizar para obtener datos meteorológicos para un código postal específico de los Estados Unidos.
- Abra el archivo Dentro del comienzo de la sección
src\pages\home\home.html
del proyecto.<ion-content>
, justo antes de la etiqueta<ion-list>
, añada la siguiente marca:<form (ngSubmit)="setZipCode()"> <ion-item> <ion-label>Type your zip code:</ion-label> <ion-input type="text" [(ngModel)]="searchInput" name="ZipCode"></ion-input> </ion-item> <button ion-button icon-left block> <ion-icon name="search"></ion-icon> Find Weather </button> </form>
Esto agrega el campo de búsqueda en la parte superior de la página y dirige que la función La referencia a
setZipCode
se ejecute cuando el usuario hace clic en el botón ngModel indica a Ionic (en realidad Angular) que asigna el valor en el campo de búsqueda a la variablesearchInput
la aplicación que verá en un segundo. Buscar tiempo . - Abra el archivo
src\pages\home\home.ts
del proyecto y agregue la siguiente declaración de variable a la parte superior de la claseHomePage
(antes delconstructor
)://Mapped to the search field searchInput: string = '';
Esto define la variable que se rellenará automáticamente con cualquier cadena que el usuario agregue al campo de búsqueda.
- Finalmente, aún en el archivo
src\pages\home\home.ts
del proyecto, agregue la siguiente función a la claseHomePage
:setZipCode() { //whenever the user enters a zip code, replace the current location //with the entered value, then show current weather for the selected //location. //Hide the keyboard if it's open, just in case Keyboard.close(); //Populate the currentLoc variable with the city name this.currentLoc = { 'zip': this.searchInput }; //Clear the Zip Code input field this.searchInput = ''; //get the weather for the specified city this.showCurrent(); }
Esta función responde al usuario pulsando el botón El código Buscar tiempo y crea un objeto de ubicación y luego llama a la función
Keyboard.close()
utiliza el complemento Ionic Keyboard para ocultar el teclado antes de iniciar la búsqueda.showCurrent
para recuperar los datos meteorológicos del código postal especificado. Si el código no lo hace, es posible que el teclado permanezca abierto, bloqueando parte de la página, a medida que la página se actualiza con los nuevos datos meteorológicos.
Cuando ejecute la aplicación, debería ver un campo de búsqueda en la parte superior de la página. Introduzca un código postal de los Estados Unidos y toque el botón para obtener datos meteorológicos para la ubicación especificada.
Agregar una página de previsión meteorológica
La API de tiempo que la aplicación utiliza tiene una API para recuperar datos de pronóstico, así que permite mostrarlo también en la aplicación. Puede agregar otra página a la aplicación, a continuación, utilice un menú u otro método de navegación para cambiar entre vistas, pero el campo de búsqueda complica ese enfoque. En su lugar, utilizaremos un componente de segmento ionic para dividir la página existente en dos partes: una para las condiciones actuales y otra para el pronóstico.
- Comience por actualizar el proveedor de clima para apoyar la obtención del pronóstico del servicio meteorológico. Abra el archivo
src\providers\weather.ts
del proyecto y agregue el código siguiente a la claseWeather
.getForecast(loc: any): Promise<any> { let url: string = this.makeDataURL(loc, 'forecast'); return this.http.get(url) .toPromise() .then(this.extractData) .catch(this.handleError); }
Para obtener el pronóstico, todo lo que el proveedor tiene que hacer es reemplazar el
weather
con laforecast
en la URL de la API, de lo contrario el código es exactamente el mismo. - A continuación, abra el archivo Eliminar la implementación actual
src\pages\home\home.html
del proyecto.<ion-list>
:<ion-list no-lines> <!--show this if there are no items in the list--> <ion-item [hidden]="c_items.length > 0"> <p><strong>Weather data is not available</strong></p> </ion-item> <!--Display the current conditions data we have --> <ion-item *ngFor="let c_item of c_items"> <p><strong>{{c_item.name}}:</strong> {{c_item.value}}</p> </ion-item> </ion-list>
Y reemplácelas por las siguientes:
<ion-segment [(ngModel)]="displayMode"> <ion-segment-button value="current" (ionSelect)="showCurrent()"> Current </ion-segment-button> <ion-segment-button value="forecast" (ionSelect)="showForecast()"> Forecast </ion-segment-button> </ion-segment>
0″> Weather data is not available
{{c_item.name}}: {{c_item.value}}
{{ f_items.length ? 'Tap an item to view the forecast for the selected period.': 'Forecast data is not available at this time.' }} {{item.period}}
Esto agrega un segmento a la página usando el componente El atributo
<ion-segment>
y define dos segmentos:<div>
con el[ngSwitch]="displayMode"
intercambia en componentes separados<ion-list>
basados en el valor asignado a la variabledisplayMode
la página.current
yforecast
. - Ahora vamos a añadir el código TypeScript que hacen que todo esto funcione. Abra el archivo
src\pages\home\home.ts
del proyecto y agregue las siguientes declaraciones de variables a la parte superior de la claseHomePage
.//This is used to set the Ionic Segment to the first segment currentMode: string = 'current'; // used to control which segment is displayed displayMode: string = this.currentMode; //holds forecast data, a separate row for each period f_items: Array<any> = []; //array of day strings used when displaying forecast data days: Array<string> = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
- Cuando la página se cargue, queremos que la aplicación muestre las condiciones actuales de forma predeterminada, por lo que agregue el siguiente código a la función
onViewDidLoad
://Switch to the Current segment this.displayMode = this.currentMode
Esto establece Agregue el código al oyente de sucesos de
this.displayMode
aresume
, el código resultante debería tener este aspecto:current
.document.addEventListener('resume', () => { //Get the local weather when the app resumes //Switch to the Current segment this.displayMode = this.currentMode //then update it with local weather conditions this.getLocalWeather(); });
- Ahora que la página muestra dos segmentos, la función Reemplace la función actual
refreshPage
necesita saber qué parte de la página debe actualizarse.refreshPage
con el código siguiente:refreshPage() { //Which page are we looking at now? if (this.displayMode === this.currentMode) { this.showCurrent(); } else { this.showForecast(); } }
- La función Agregue las siguientes líneas a la función antes de la llamada a
setZipCode
carga por defecto a las condiciones actuales de carga cuando se introduce un código postal, por lo que debe cambiar a la pestaña Actual antes de obtener resultados.this.showCurrent()
://Switch to the 'current' tab this.displayMode = this.currentMode;
La función completa debería tener este aspecto:
setZipCode() { //whenever the user enters a zip code, replace the current location //with the entered value, then show current weather for the selected //location. //Hide the keyboard if it's open, just in case Keyboard.close(); //Populate the currentLoc variable with the city name this.currentLoc = { 'zip': this.searchInput }; //Clear the Zip Code input field this.searchInput = ''; //Switch to the 'current' tab this.displayMode = this.currentMode; //get the weather for the specified city this.showCurrent(); }
- Por último, agregue la función
showForecast
a la claseHomePage
:showForecast() { //clear out the previous array contents this.f_items = []; //Create the loading indicator let loader = this.loadingCtrl.create({ content: "Retrieving forecast..." }); //Show the loading indicator loader.present(); this.weather.getForecast(this.currentLoc).then( data => { //Hide the loading indicator loader.dismiss(); //Now, populate the array with data from the weather service //Do we have some data? if (data) { //Then lets build the results array we need //Process each forecast period in the array for (let period of data.list) { //Create a 'record' consisting of a time period's results let weatherValues: any = this.formatWeatherData(period); //Append this, along with the time period information, into the forecast //items array. //Get the forecast date as a date object let d = new Date(period.dt_txt); //Determe the day of the week let day = this.days[d.getDay()]; //And the time let tm = d.toLocaleTimeString(); //Create a new object in the results array for this period this.f_items.push({ 'period': day + ' at ' + tm, 'values': weatherValues }); } } else { //This really should never happen console.error('Error displaying weather data: Data object is empty'); } }, error => { //Hide the loading indicator loader.dismiss(); console.error("Error retrieving weather data"); console.dir(error); this.showAlert(error); } ); }
Esta función obtiene los datos de pronóstico, luego los formatea para mostrarlo en dos páginas. En primer lugar, se construye una serie de períodos de tiempo que representan los diferentes períodos de pronóstico. Luego, para cada período, agrega un objeto que contiene los datos de pronóstico para ese período. El segmento de pronóstico de la página muestra la lista de períodos de pronóstico y, al pulsar en una entrada, la aplicación eventualmente (verá cómo en la siguiente sección) abre una página separada para mostrar los detalles.
En este punto, si ejecuta la aplicación, debería ver lo siguiente:
Toque la pestaña de pronóstico y verá la lista de períodos de previsión que se muestra en la siguiente figura:
Cuando pulsa en un elemento de pronóstico, no pasa nada (por ahora); Que es porque necesitamos una página para mostrar los datos, y no ha agregado uno todavía.
Cómo añadir una página de detalles del tiempo
- Para agregar una nueva página a la aplicación, en el Explorador de soluciones, haga clic con el botón secundario en la carpeta En la lista de opciones que aparece, seleccione Visual Studio creará una nueva carpeta denominada
src\pages
, seleccione Ionic 2 Page , dale un nombre deWeatherDetail
ensrc\pages\
y la rellenará con los archivos de origen de la nueva página:weather-detail.ts
,weather-detail.html
yweather-detail.scss
.WeatherDetail
yWeatherDetail
clic en el botón Add . Agregar -> Nuevo elemento .... - Como cuando agregó un proveedor de la aplicación, cuando se agrega una página, es necesario actualizar la configuración de la aplicación para utilizarlo. Abra el proyecto de
src\app\app.module.ts
archivo y agregue la siguienteimport
instrucción al principio del archivo:import { WeatherDetailPage } from '../pages/weatherdetail/weatherdetail';
- A continuación, agregue una referencia al
WeatherDetailPage
componente aldeclarations
yentryComponents
matrices como se muestra a continuación:@NgModule({ declarations: [ MyApp, HomePage, WeatherDetailPage ], imports: [ IonicModule.forRoot(MyApp) ], bootstrap: [IonicApp], entryComponents: [ MyApp, HomePage, WeatherDetailPage ], providers: [Weather, { provide: ErrorHandler, useClass: IonicErrorHandler }] }) export class AppModule { }
- Abrir el proyecto de
src\pages\weatherdetail\weatherdetail.html
y reemplazar su contenido con el siguiente marcado:<ion-header> <ion-navbar> <ion-title>Forecast</ion-title> </ion-navbar> </ion-header> <ion-content padding> <ion-list> <!--show this if there are no items in the list--> <ion-item [hidden]="forecast.values.length > 0"> <p><strong>Weather data is not available</strong></p> </ion-item> <ion-item [hidden]="forecast.values.length < 1"> Period: {{forecast.period}} </ion-item> <ion-item *ngFor="let item of forecast.values"> <p><strong>{{item.name}}:</strong> {{item.value}}</p> </ion-item> </ion-list> </ion-content> <ion-footer> <ion-toolbar> <ion-title>Visual Studio Tools for Apache Cordova</ion-title> </ion-toolbar> </ion-footer>
Esto crea una página que muestra el elemento de predicción seleccionado como una lista de
name
yvalue
los valores. - Abra el proyecto de
src\pages\weatherdetail\weatherdetail.ts
archivo y reemplazar su contenido con el siguiente código:import { Component } from [email protected]/core'; import { NavController, NavParams } from 'ionic-angular'; @Component({ selector: 'page-weather-detail', templateUrl: 'weatherdetail.html' }) export class WeatherDetailPage { forecast: any; constructor(public navCtrl: NavController, public navParams: NavParams) { //Pull the selected forecast off of navParams this.forecast = this.navParams.get('forecast'); } ionViewDidLoad() { console.log('Weather Detail page loaded'); } }
Observe que no hay ningún código real en la página, que se debe a la plantilla HTML se encarga de hacer que el Ionic de datos y se encarga de la página de navegación automáticamente. Los tres cambios importantes son:
- La adición de un
NavParams
componente a la página, que es responsable de transmitir datos entre páginas. - La adición de una
forecast
variable:forecast: any;
Esta variable es el almacenamiento para el objeto de previsión pasa a la página cuando se abre. Contiene los datos correspondientes al período de predicción actual. La página HTML referencias esta variable como la fuente de los datos que hace que en la página.
- La adición de una sola línea de código al
constructor
:this.forecast = this.navParams.get('forecast');
Esto asigna el local de
this.forecast
objeto para los datos pasados en elforecast
objeto envía a través delNavParams
componente
- La adición de un
- Ahora tenemos que decirle al
forecast
segmento de la forma de abrir la página de detalles de pronóstico cuando el usuario pulsa sobre un elemento de la lista. Abrir el proyecto desrc\pages\home\home.ts
y agregue la siguienteimport
instrucción al principio del archivo:import { WeatherDetailPage } from '../weatherdetail/weatherdetail';
- Todavía en
src\pages\home\home.ts
, agregue laviewForecast
función para la clase:viewForecast(item) { //When the user selects one of the Forecast periods, //open up the details page for the selected period. this.nav.push(WeatherDetailPage, { 'forecast': item }); }
HTML de la página ya tiene una referencia a esta función:
<button detail-push ion-item *ngFor="let item of f_items" (click)="viewForecast(item)"> <ion-icon name="time" item-left></ion-icon> {{item.period}} </button>
Al ejecutar la aplicación ahora, usted debería ser capaz de abrir la previsión de un toque en uno de los períodos de predicción de la lista:
navegación de la página es manejado por jónico y angular, se encargan de añadir la flecha hacia atrás en la esquina izquierda de la barra de herramientas y el cierre de la página cuando se ha intervenido.
¡Eso es! Usted ha completado la Aplicación.