- TypeScript Blueprints
- Ivo Gabe de Wolff
- 609字
- 2021-07-14 10:59:30
The main component
As you can see in the screenshot in the introduction of this chapter, this component should have a textbox, a button, and three tabs. Under the tabs, these component will show the forecast or the About page.
Using our other components
We can use our components that we have already written by adding them to the directives
section and using their tag names in the template.
Two-way bindings
To get the value of the input box, we need two-way bindings. We can use the ngModel
directive for that. The syntax combines the syntaxes of the two one-way bindings: [(ngModel)]="property"
. The directive is again a built-in one, so we don't have to import it.
Using this two-way binding, we can automatically update the weather widget after every key press. That would cause a lot of requests to the server, and especially on slow connections, that's not desired.
To prevent these issues, we will add two separate properties. The property location will contain the content of the input and activeLocation
will contain the location, which is being shown.
Listening to our event
We can listen to our event, just like we did with other events. We can access the event content with $event
. Such a listener will look like (correct-location)="correctLocation($event)
. When the server responds with the forecast, it also provides the name of the location. If the user had a small typo in the name, the response will correct that. This event will be fired in such a case and the name will be corrected in the input box.
Geolocation API
Because our forecast widget supports coordinates, we can use the geolocation API to set the initial location. That API can give the coordinates where the device is located (roughly). Later on, we will use this API to set the widget to the current location when the page loads as shown here:
navigator.geolocation.getCurrentPosition(position => { const location = `Coordinate ${ position.coords.latitude } ${ position.coords.longitude }`; this.location = location; this.activeLocation = location; });
Tip
Template string
Template strings, not to be confused with Angular templates, are strings wrapped in backticks (`
). These strings can be multiline and can contain expressions between ${
and }
.
Component sources
As usual, we start by importing Angular. We also have to import the two components we have already written. We use an enumeration again to store the state of the component:
import { Component } from "angular2/core"; import { Forecast } from "./forecast"; import { About } from "./about"; enum State { Today, Tomorrow, About }
The template will use the two-way binding on the input
element:
@Component({ selector: "weather-widget", directives: [Forecast, About], template: ` <input [(ngModel)]="location" (keyup.enter)="clickGo()" (blur)="clickGo()" /> <button (click)="clickGo()">Go</button> <div class="tabs"> <a href="javascript:;" [class.selected]="selectedTab === 0" (click)="selectTab(0)">Today</a> <a href="javascript:;" [class.selected]="selectedTab === 1" (click)="selectTab(1)">Tomorrow</a> <a href="javascript:;" [class.selected]="selectedTab === 2" (click)="selectTab(2)">About</a> </div> <div class="content" [class.is-dirty]="isDirty" *ngIf="selectedTab === 0 || selectedTab === 1"> <weather-forecast [location]="activeLocation" [tomorrow]="selectedTab === 1" (correctLocation)="correctLocation($event)" /> </div> <div class="content" *ngIf="selectedTab === 2"> <about-page [location]="activeLocation" /> </div> `,
Binding to class.selected
means that the element will have the selected
class if the bound value is true. After the template, we can add some styles as shown here:
styles: [ `.tabs > a { display: inline-block; padding: 5px; margin-top: 5px; border: 1px solid #57BEDE; border-bottom: 0px none; text-decoration: none; } .tabs>a.selected { background-color: #57BEDE; color: #fff; } .content { border-top: 5px solid #57BEDE; } .is-dirty { opacity: 0.4; background-color: #ddd; }` ] })
In the constructor, we can use the geolocation API to get the coordinates of the current position:
export class Widget { constructor() { navigator.geolocation.getCurrentPosition(position => { const location = `Coordinate ${ position.coords.latitude } ${ position.coords.longitude }`; this.location = location; this.activeLocation = location; }); } location: string = "Utrecht,NL"; activeLocation: string = "Utrecht,NL"; get isDirty() { return this.location !== this.activeLocation; } clickGo() { this.activeLocation = this.location; } correctLocation(location: string) { if (!this.isDirty) this.location = location; this.activeLocation = location; } selectedTab = 0; selectTab(index: number) { this.selectedTab = index; } }
- Visual C++程序設計學習筆記
- 編程的修煉
- PostgreSQL Cookbook
- Learning RabbitMQ
- Internet of Things with the Arduino Yún
- 信息安全技術
- Troubleshooting PostgreSQL
- SQL Server 2016數據庫應用與開發習題解答與上機指導
- RISC-V體系結構編程與實踐(第2版)
- SQL Server實用教程(SQL Server 2008版)
- App Inventor創意趣味編程進階
- 零基礎學Kotlin之Android項目開發實戰
- Access 2010中文版項目教程
- HTML+CSS+JavaScript編程入門指南(全2冊)
- HTML5+CSS3+jQuery Mobile APP與移動網站設計從入門到精通