- 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; } }
- Java異步編程實戰
- PaaS程序設計
- Learning RabbitMQ
- VSTO開發入門教程
- 小程序,巧運營:微信小程序運營招式大全
- Apache Mahout Clustering Designs
- 可解釋機器學習:模型、方法與實踐
- 劍指MySQL:架構、調優與運維
- Learning Three.js:The JavaScript 3D Library for WebGL
- 第一行代碼 C語言(視頻講解版)
- HTML5從入門到精通(第4版)
- 基于SpringBoot實現:Java分布式中間件開發入門與實戰
- 一本書講透Java線程:原理與實踐
- Python+Tableau數據可視化之美
- JavaScript Unit Testing