angular-docs-cn/public/docs/dart/latest/tutorial/toh-pt6.jade

192 lines
7.1 KiB
Plaintext

extends ../../../ts/_cache/tutorial/toh-pt6.jade
block includes
include ../_util-fns
- var _Http = 'BrowserClient';
- var _Angular_Http = 'Dart <code>BrowserClient</code>'
- var _httpUrl = 'https://pub.dartlang.org/packages/http'
- var _Angular_http_library = 'Dart <a href="' + _httpUrl + '"><b>http</b></a> package'
- var _HttpModule = 'BrowserClient'
- var _JSON_stringify = 'JSON.encode'
block start-server-and-watch
:marked
### Keep the app compiling and running
Open a terminal/console window.
Start the Dart compiler, watch for changes, and start our server by entering the command:
code-example(language="bash").
pub serve
block http-library
:marked
We'll be using the !{_Angular_http_library}'s
`BrowserClient` class to communicate with a server.
### Pubspec updates
Update package dependencies by adding the
`stream_transformers` and !{_Angular_http_library}s.
We also need to add a `resolved_identifiers` entry, to inform the [angular2
transformer][ng2x] that we'll be using `BrowserClient`. (For an explanation of why
this extra configuration is needed, see the [HTTP client chapter][guide-http].) We'll
also need to use `Client` from http, so let's add that now as well.
Update `pubspec.yaml` to look like this (additions are highlighted):
[guide-http]: ../guide/server-communication.html#!#http-providers
[ng2x]: https://github.com/angular/angular/wiki/Angular-2-Dart-Transformer
- var stylePattern = { pnk: /(http.*|stream.*|resolved_identifiers:|Browser.*|Client.*)/gm };
+makeExcerpt('pubspec.yaml', 'additions', null, stylePattern)
block http-providers
:marked
Before our app can use `#{_Http}`, we have to register it as a service provider.
We should be able to access `!{_Http}` services from anywhere in the application.
So we register it in the `bootstrap` call where we
launch the application and its root `AppComponent`.
+makeExcerpt('app/main.ts','v1')
:marked
Notice that we supply `!{_HttpModule}` in a list, as the second parameter to
the `bootstrap` method. This has the same effect as the `providers` list in
`@Component` annotation.
block backend
:marked
We want to replace `BrowserClient`, the service that talks to the remote server,
with the in-memory web API service.
Our in-memory web API service, shown below, is implemented using the
`http` library `MockClient` class.
All `http` client implementations share a common `Client` interface, so
we'll have our app use the `Client` type so that we can freely switch between
implementations.
block dont-be-distracted-by-backend-subst
//- No backend substitution but we do need to comment on the changes to Hero.
:marked
As is common for web API services, our mock in-memory service will be
encoding and decoding heroes in JSON format, so we enhance the `Hero`
class with these capabilities:
+makeExample('lib/hero.dart')
block get-heroes-details
:marked
To get the list of heroes, we first make an asynchronous call to
`http.get()`. Then we use the `_extractData` helper method to decode the
response body.
block observables-section-intro
:marked
Recall that `HeroService.getHeroes()` awaits for an `http.get()`
response and yields a _Future_ `List<Hero>`, which is fine when we are only
interested in a single result.
block search-criteria-intro
:marked
A [StreamController][], as its name implies, is a controller for a [Stream][] that allows us to
manipulate the underlying stream by adding data to it, for example.
In our sample, the underlying stream of strings (`_searchTerms.stream`) represents the hero
name search patterns entered by the user. Each call to `search` puts a new string into
the stream by calling `add` over the controller.
[Stream]: https://api.dartlang.org/stable/dart-async/Stream-class.html
[StreamController]: https://api.dartlang.org/stable/dart-async/StreamController-class.html
block observable-transformers
:marked
Fortunately, there are stream transformers that will help us reduce the request flow.
We'll make fewer calls to the `HeroSearchService` and still get timely results. Here's how:
* `transform(new Debounce(... 300)))` waits until the flow of search terms pauses for 300
milliseconds before passing along the latest string. We'll never make requests more frequently
than 300ms.
* `distinct()` ensures that we only send a request if a search term has changed.
There's no point in repeating a request for the same search term.
* `transform(new FlatMapLatest(...))` applies a map-like transformer that (1) calls our search
service for each search term that makes it through the debounce and distinct gauntlet and (2)
returns only the most recent search service result, discarding any previous results.
* `handleError()` handles errors. Our simple example prints the error to the console; a real
life application should do better.
block filetree
.filetree
.file angular2_tour_of_heroes
.children
.file lib
.children
.file app_component.css
.file app_component.dart
.file dashboard_component.css
.file dashboard_component.dart
.file dashboard_component.html
.file hero.dart
.file hero_detail_component.css
.file hero_detail_component.dart
.file hero_detail_component.html
.file hero_search_component.css (new)
.file hero_search_component.dart (new)
.file hero_search_component.html (new)
.file hero_search_service.dart (new)
.file hero_service.dart
.file heroes_component.css
.file heroes_component.dart
.file heroes_component.html
.file in_memory_data_service.dart (new)
.file web
.children
.file main.dart
.file index.html
.file styles.css
.file pubspec.yaml
block file-summary
+makeTabs(
`toh-6/dart/lib/dashboard_component.dart,
toh-6/dart/lib/dashboard_component.html,
toh-6/dart/lib/hero.dart,
toh-6/dart/lib/hero_detail_component.dart,
toh-6/dart/lib/hero_detail_component.html,
toh-6/dart/lib/hero_service.dart,
toh-6/dart/lib/heroes_component.css,
toh-6/dart/lib/heroes_component.dart,
toh-6/dart/lib/in_memory_data_service.dart`,
',,,,,,,,',
`lib/dashboard_component.dart,
lib/dashboard_component.html,
lib/hero.dart,
lib/hero_detail_component.dart,
lib/hero_detail_component.html,
lib/hero_service.dart,
lib/heroes_component.css,
lib/heroes_component.dart,
lib/in_memory_data_service.dart`)
+makeTabs(
`toh-6/dart/lib/hero_search_component.css,
toh-6/dart/lib/hero_search_component.dart,
toh-6/dart/lib/hero_search_component.html,
toh-6/dart/lib/hero_search_service.dart`,
null,
`lib/hero_search_component.css,
lib/hero_search_component.dart,
lib/hero_search_component.html,
lib/hero_search_service.dart`)
+makeTabs(
`toh-6/dart/pubspec.yaml,
toh-6/dart/web/main.dart`,
null,
`pubspec.yaml,
web/main.dart`)