- Dart:Scalable Application Development
- Davy Mitchell Sergey Akopkokhyants Ivo Balbaert
- 299字
- 2021-07-09 18:56:29
Consuming application
We now have two parts of the solution: the collected data and the web service to publish it. The next step is to build a client application that will talk to the web service. Initially, we will have a details grid view (or table
for the HTML-minded) of the ten latest incoming data.
Rather than having the user update the page, the screen will auto-update periodically with the latest earthquake information.
Packaging the grid
The grid display may be useful for other applications, so it will be split off into its own project as the package webgridview
, as shown here:
name: 'GridViewer' version: 0.0.1 description: A grid viewer for GeoJSON data. environment: sdk: '>=1.0.0 <2.0.0' dependencies: browser: '>=0.10.0 <0.11.0' intl: any webgridview: path: ../webgridview/
The package can be referenced in the pubspec.yaml
as a local package.
Initiating the real-time updates
The main
function in main.dart
will perform an initial update of the grid and then initiate a Timer
that will update the page on a periodic basis:
void main() { performUpdate(null); updater = new Timer.periodic(new Duration(seconds: 10), performUpdate); }
The periodic timer handler performUpdate
is provided a Timer
object as a parameter when it is triggered every 10 seconds. When we are directly calling it, null
is provided instead of the Timer
instance.
Performing the update
The two elements being updated are the current time, with a countdown to the next refresh, and the grid of the data. Let's have a look at the following code snippet:
void performUpdate(Timer triggerTimer) { DivElement outputDiv = querySelector('#timestatus'); DateTime currentDateTime = new DateTime.now(); DateFormat timeStamp = new DateFormat("hh:mm a"); if (triggerTimer != null) { secondsToUpdate -= 10; } else updateDataView(); if (secondsToUpdate == 0) { updateDataView(); secondsToUpdate = 60; } outputDiv.text = "${timeStamp.format(currentDateTime)} - $secondsToUpdate seconds until refresh."; }
The secondsToUpdate
variable is decremented from 60
to 0
and triggers an update every six calls so that the display changes every minute.
Fetching the JSON
The updateDataView
function in the main.dart
file covers fetching the data and updating the grid view:
... HttpRequest.getString(jsonSrc).then((String data) { outputDiv.children.clear(); List items; try { items = JSON.decode(data); } catch (exception, stackTrace) { print(exception); print(stackTrace); } ...
The DivElement
outputDiv
is the container for the dynamically updating content, which is entirely cleared at each update. The incoming JSON data is decoded and stored in the List
object named items
.
Configuring the grid view control
The data for the grid is provided as a structure of a list of lists. The first list in the structure forms the header of the table. Let's have a look at the following code snippet:
... if (items != null) { List allQuakeData = []; allQuakeData.add( ['Time', 'Magnitude', 'Type', 'Tsunami', 'Place', 'Sig', 'Link']); items.forEach((String post) { Map decodedData = JSON.decode(post); List quakeData = []; quakeData.add(convertTime(decodedData['properties']['time'])); quakeData.add(decodedData['properties']['mag']); quakeData.add(decodedData['properties']['type']); quakeData.add(decodedData['properties']['tsunami']); quakeData.add(decodedData['properties']['place']); quakeData.add(decodedData['properties']['sig']); quakeData.add(decodedData['properties']['url']); allQuakeData.add(quakeData); }); outputDiv.append(Gridview.getTable(allQuakeData)); } ...
The JSON items are iterated over and the values for the grid are extracted. The only value not used directly is the time
field, which requires formatting.
Formatting the time
The time provided for each feature in the JSON is an integer number. This is the time recorded as the number of milliseconds since a point in time, usually called the epoch (which is the start of the year 1970 at exactly 00:00:00 1970-01-01). Let's have a look at the following code snippet:
String convertTime(int milliTime) { DateTime dt = new DateTime.fromMillisecondsSinceEpoch(milliTime); DateFormat timeStamp = new DateFormat("hh:mm:ss a"); return timeStamp.format(dt); }
The DateTime
format provides the named constructor fromMillisecondsSinceEpoch
, which returns a regular DateTime
object. This can be converted to a string and added to the table for display in the data grid.
Working with date and time
Dates and times are very important data types in all kinds of applications, and the Dart intl
package has functionality for parsing and formatting dates. Countries have specific formatting and ordering preferences, and, of course, everyone is different and uses multiple formats.
The format used in the grid view may not be to your liking and may be better displayed as a 24-hour format. The project timesdate
in the sample code for this chapter explores the different date formats that are available. This short command-line program shows some of the options available; the list is quite long, and it is fully documented in the intl
package documentation. Let's have a look at the following code snippet:
DateTime currentTime = new DateTime.now(); print("\nDate and Time Demo"); printTime(currentTime, "hh:mm a"); printTime(currentTime, "HH:MM"); printTime(currentTime, "y"); printTime(currentTime, "d"); printTime(currentTime, "M"); printTime(currentTime, "EEEE"); …
The preceding code renders the following output display, which will vary according to the time at which it is executed:
Date and Time Demo hh:mm a 04:12 PM HH:MM 16:06 y 2015 d 13 EEEE Saturday
The function printTime
formats the input DateTime
to the desired style. The padRight
method on the String
object is used to make a simple table by adding spaces to pad out the string to 12 characters, as shown here:
void printTime(DateTime dt, String format) { DateFormat timeStamp = new DateFormat(format); print("\t${format.padRight(12)} ${timeStamp.format(dt)}"); }
The second part of the program allows a date to be entered by using the stdin readlineSync
method. The user can enter a blank line to exit. The string is parsed according to the format yyyy-MM-dd
, and the weekday is displayed if it is successfully parsed:
while (true) { String userDate = ""; print("\nPlease enter a date (yyyy-MM-dd):"); try { DateFormat timeStamp = new DateFormat("yyyy-MM-dd"); DateFormat outputFmt = new DateFormat("EEEE"); userDate = stdin.readLineSync(); if (userDate.length == 0) exit(0); print(outputFmt.format(timeStamp.parse(userDate))); } catch (exception, stacktrace) { print('Error parsing the entered date.'); print(exception); print(stacktrace); } }
The parsing is wrapped in try catch
to deal with an exception raise with a failed parse of a date string.
Building the table
The class GridView
, located in the file lib/src/webgridview_base.dart
, prepares a table from the list of lists provided by the calling web page. The static method getTable
performs the task. As it is static, an instance of the class is not required to call this function. Let's have a look at the following code snippet:
static TableElement getTable(List rows) { TableElement te = new TableElement(); rows.forEach((row) => addRow(te, row)); return te; }
The addRow
function iterates over the columns in the results. The header row is added as a regular row as the CSS will take care of the special formatting of the first row, as shown here:
static addRow(TableElement table, List cols) { TableRowElement tableRow = table.addRow(); cols.forEach((column) { TableCellElement tableCell = tableRow.addCell(); String content = column.toString(); if (content.startsWith('http')) { content = "<a href=\"$content\">Link</a>"; tableCell.appendHtml(content); } else tableCell.text = content; }); }
The content is added as text to the table cell, with one special case of strings that start with http
. These URLs are formatted into HTML with a generic link text, and the appendHtml
method is used to ensure that the text is not sanitized before being added to the page.
Showing the page
Launching the application in Dartium will show the index.html
page:

Keep this page open over a period of time and the table will update smoothly as new data becomes available. Events from outside the USA do appear, though less often. It is fairly rare, but the Type column does not always read 'earthquake'.
- Getting Started with Citrix XenApp? 7.6
- 企業(yè)級Java EE架構(gòu)設(shè)計精深實踐
- GraphQL學(xué)習(xí)指南
- 造個小程序:與微信一起干件正經(jīng)事兒
- Python for Secret Agents:Volume II
- Java設(shè)計模式及實踐
- Python:Master the Art of Design Patterns
- Terraform:多云、混合云環(huán)境下實現(xiàn)基礎(chǔ)設(shè)施即代碼(第2版)
- Java零基礎(chǔ)實戰(zhàn)
- Java程序設(shè)計與項目案例教程
- C語言程序設(shè)計實訓(xùn)教程與水平考試指導(dǎo)
- JavaScript編程精解(原書第2版)
- C Primer Plus(第6版)中文版【最新修訂版】
- C語言程序設(shè)計教程
- SQL Server 2014 Development Essentials