parent
73105aa7d6
commit
70fb3e958b
|
@ -1,4 +1,4 @@
|
|||
<h1>HTTP Sample</h1>
|
||||
<h1>HttpClient Example</h1>
|
||||
<div>
|
||||
<input type="checkbox" id="heroes" [checked]="showHeroes" (click)="toggleHeroes()">
|
||||
<label for="heroes">Heroes</label>
|
||||
|
@ -17,8 +17,13 @@
|
|||
</div>
|
||||
|
||||
<app-heroes *ngIf="showHeroes"></app-heroes>
|
||||
<hr />
|
||||
<app-messages></app-messages>
|
||||
<hr />
|
||||
<app-config *ngIf="showConfig"></app-config>
|
||||
<hr />
|
||||
<app-downloader *ngIf="showDownloader"></app-downloader>
|
||||
<hr />
|
||||
<app-uploader *ngIf="showUploader"></app-uploader>
|
||||
<hr />
|
||||
<app-package-search *ngIf="showSearch"></app-package-search>
|
||||
|
|
|
@ -7,7 +7,7 @@ import { Config, ConfigService } from './config.service';
|
|||
selector: 'app-config',
|
||||
templateUrl: './config.component.html',
|
||||
providers: [ ConfigService ],
|
||||
styles: ['.error {color: red;}']
|
||||
styles: ['.error { color: #b30000; }']
|
||||
})
|
||||
export class ConfigComponent {
|
||||
error: any;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<h3>Download the textfile</h3>
|
||||
<h2>Download the text file</h2>
|
||||
<button (click)="download()">Download</button>
|
||||
<button (click)="clear()">clear</button>
|
||||
<p *ngIf="contents">Contents: "{{contents}}"</p>
|
||||
|
|
|
@ -1,88 +1,58 @@
|
|||
/* HeroesComponent's private CSS styles */
|
||||
.search input {
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.heroes {
|
||||
margin: 0 0 2em 0;
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
width: 15em;
|
||||
}
|
||||
|
||||
.heroes li {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
background-color: #EEE;
|
||||
margin: .5em;
|
||||
padding: .3em 0;
|
||||
height: 1.6em;
|
||||
border-radius: 4px;
|
||||
width: 19em;
|
||||
}
|
||||
|
||||
.heroes li:hover {
|
||||
color: #607D8B;
|
||||
background-color: #DDD;
|
||||
left: .1em;
|
||||
}
|
||||
|
||||
.heroes a {
|
||||
color: #888;
|
||||
text-decoration: none;
|
||||
position: relative;
|
||||
color: black;
|
||||
display: block;
|
||||
width: 250px;
|
||||
font-size: 1.2rem;
|
||||
background-color: #eee;
|
||||
margin: .5em 0;
|
||||
padding: .5em 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.heroes a:hover {
|
||||
color:#607D8B;
|
||||
color: #2c3a41;
|
||||
background-color: #e6e6e6;
|
||||
}
|
||||
|
||||
.heroes .badge {
|
||||
display: inline-block;
|
||||
font-size: small;
|
||||
padding: .5em .6em;
|
||||
color: white;
|
||||
padding: 0.8em 0.7em 0 0.7em;
|
||||
background-color: #607D8B;
|
||||
line-height: 1em;
|
||||
position: relative;
|
||||
left: -1px;
|
||||
top: -4px;
|
||||
height: 1.8em;
|
||||
background-color: #435B60;
|
||||
min-width: 16px;
|
||||
text-align: right;
|
||||
margin-right: .8em;
|
||||
border-radius: 4px 0 0 4px;
|
||||
}
|
||||
|
||||
.button {
|
||||
background-color: #eee;
|
||||
border: none;
|
||||
padding: 5px 10px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #cfd8dc;
|
||||
}
|
||||
|
||||
button.delete {
|
||||
position: relative;
|
||||
left: 24em;
|
||||
top: -32px;
|
||||
background-color: gray !important;
|
||||
position: absolute;
|
||||
right: -8px;
|
||||
top: 5px;
|
||||
background-color: gray;
|
||||
color: white;
|
||||
display: inherit;
|
||||
padding: 5px 8px;
|
||||
width: 2em;
|
||||
}
|
||||
|
||||
input {
|
||||
font-size: 100%;
|
||||
margin-bottom: 2px;
|
||||
width: 11em;
|
||||
}
|
||||
|
||||
.heroes input {
|
||||
position: relative;
|
||||
top: -3px;
|
||||
width: 12em;
|
||||
max-width: 12rem;
|
||||
padding: .25rem;
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<h3>Heroes</h3>
|
||||
<div>
|
||||
<label>Hero name:
|
||||
<input #heroName />
|
||||
</label>
|
||||
<h2>Heroes</h2>
|
||||
<div class="search">
|
||||
<label for="hero-name">Hero name: </label>
|
||||
<input type="text" #heroName id="hero-name">
|
||||
|
||||
<!-- (click) passes input value to add() and then clears the input -->
|
||||
<button (click)="add(heroName.value); heroName.value=''">
|
||||
add
|
||||
Add hero
|
||||
</button>
|
||||
<button (click)="search(heroName.value)">
|
||||
search
|
||||
Search
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
@ -17,8 +17,11 @@
|
|||
<a (click)="edit(hero)">
|
||||
<span class="badge">{{ hero.id || -1 }}</span>
|
||||
<span *ngIf="hero!==editHero">{{hero.name}}</span>
|
||||
<input *ngIf="hero===editHero" [(ngModel)]="hero.name"
|
||||
(blur)="update()" (keyup.enter)="update()">
|
||||
<input type="text"
|
||||
*ngIf="hero===editHero"
|
||||
[(ngModel)]="hero.name"
|
||||
(blur)="update()"
|
||||
(keyup.enter)="update()">
|
||||
</a>
|
||||
<button class="delete" title="delete hero"
|
||||
(click)="delete(hero)">x</button>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div *ngIf="messageService.messages.length">
|
||||
<h3>Messages</h3>
|
||||
<h2>Messages</h2>
|
||||
<button class="clear" (click)="messageService.clear()">clear</button>
|
||||
<br>
|
||||
<ol>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<!-- #docplaster -->
|
||||
<h3>Search Npm Packages</h3>
|
||||
<h2>Search Npm Packages</h2>
|
||||
<p><i>Searches when typing stops. Caches for 30 seconds.</i></p>
|
||||
<!-- #docregion search -->
|
||||
<input (keyup)="search(getValue($event.target))" id="name" placeholder="Search"/>
|
||||
<input type="text" (keyup)="search(getValue($event.target))" id="name" placeholder="Search"/>
|
||||
<!-- #enddocregion search -->
|
||||
<input type="checkbox" id="refresh" [checked]="withRefresh" (click)="toggleRefresh()">
|
||||
<label for="refresh">with refresh</label>
|
||||
|
|
|
@ -8,6 +8,7 @@ import { NpmPackageInfo, PackageSearchService } from './package-search.service';
|
|||
@Component({
|
||||
selector: 'app-package-search',
|
||||
templateUrl: './package-search.component.html',
|
||||
styles: ['input { margin-bottom: .5rem; }'],
|
||||
providers: [ PackageSearchService ]
|
||||
})
|
||||
export class PackageSearchComponent implements OnInit {
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
<h3>Upload file</h3>
|
||||
<h2>Upload a file</h2>
|
||||
<form enctype="multipart/form-data" method="post">
|
||||
<div>
|
||||
<label for="picked">Choose file to upload</label>
|
||||
<div>
|
||||
<input type="file" id="picked" #picked
|
||||
(click)="message=''"
|
||||
(change)="onPicked(picked)">
|
||||
</div>
|
||||
<label for="picked">Choose a file to upload:</label>
|
||||
<input type="file"
|
||||
id="picked"
|
||||
#picked
|
||||
(click)="message=''"
|
||||
(change)="onPicked(picked)">
|
||||
|
||||
</div>
|
||||
<p *ngIf="message">{{message}}</p>
|
||||
</form>
|
||||
|
|
|
@ -4,6 +4,7 @@ import { UploaderService } from './uploader.service';
|
|||
@Component({
|
||||
selector: 'app-uploader',
|
||||
templateUrl: './uploader.component.html',
|
||||
styles: ['input[type=file] { font-size: 1.2rem; margin-top: 1rem; display: block; }'],
|
||||
providers: [ UploaderService ]
|
||||
})
|
||||
export class UploaderComponent {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>HttpClient Demo</title>
|
||||
<title>HttpClient Example</title>
|
||||
<base href="/">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Communicating with backend services using HTTP
|
||||
|
||||
Most front-end applications need to communicate with a server over the HTTP protocol, in order to download or upload data and access other back-end services.
|
||||
Angular provides a simplified client HTTP API for Angular applications, the `HttpClient` service class in `@angular/common/http`.
|
||||
Angular provides a client HTTP API for Angular applications, the `HttpClient` service class in `@angular/common/http`.
|
||||
|
||||
The HTTP client service offers the following major features.
|
||||
|
||||
|
@ -371,7 +371,7 @@ The following example shows how you can pipe a failed request to the `retry()` o
|
|||
|
||||
In addition to fetching data from a server, `HttpClient` supports other HTTP methods such as PUT, POST, and DELETE, which you can use to modify the remote data.
|
||||
|
||||
The sample app for this guide includes a simplified version of the "Tour of Heroes" example
|
||||
The sample app for this guide includes an abridged version of the "Tour of Heroes" example
|
||||
that fetches heroes and enables users to add, delete, and update them.
|
||||
The following sections show examples of the data-update methods from the sample's `HeroesService`.
|
||||
|
||||
|
@ -563,7 +563,8 @@ for each `HttpClient` method call.
|
|||
|
||||
To implement an interceptor, declare a class that implements the `intercept()` method of the `HttpInterceptor` interface.
|
||||
|
||||
Here is a do-nothing _noop_ interceptor that simply passes the request through without touching it:
|
||||
Here is a do-nothing _noop_ interceptor that passes the request through without touching it:
|
||||
|
||||
<code-example
|
||||
path="http/src/app/http-interceptors/noop-interceptor.ts"
|
||||
header="app/http-interceptors/noop-interceptor.ts">
|
||||
|
@ -582,7 +583,7 @@ export abstract class HttpHandler {
|
|||
|
||||
Like `intercept()`, the `handle()` method transforms an HTTP request into an `Observable` of [`HttpEvents`](#interceptor-events) which ultimately include the server's response. The `intercept()` method could inspect that observable and alter it before returning it to the caller.
|
||||
|
||||
This _no-op_ interceptor simply calls `next.handle()` with the original request and returns the observable without doing a thing.
|
||||
This _no-op_ interceptor calls `next.handle()` with the original request and returns the observable without doing a thing.
|
||||
|
||||
### The _next_ object
|
||||
|
||||
|
@ -654,12 +655,12 @@ There are many more interceptors in the complete sample code.
|
|||
|
||||
Angular applies interceptors in the order that you provide them.
|
||||
For example, consider a situation in which you want to handle the authentication of your HTTP requests and log them before sending them to a server. To accomplish this task, you could provide an `AuthInterceptor` service and then a `LoggingInterceptor` service.
|
||||
Outgoing requests would flow from the `AuthInterceptor` to the `LoggingInterceptor`.
|
||||
Outgoing requests would flow from the `AuthInterceptor` to the `AuthInterceptor`.
|
||||
Responses from these requests would flow in the other direction, from `LoggingInterceptor` back to `AuthInterceptor`.
|
||||
The following is a visual representation of the process:
|
||||
|
||||
<div class="lightbox">
|
||||
<img src="generated/images/guide/http/interceptor-order.svg" alt="Interceptor order">
|
||||
<img src="generated/images/guide/http/interceptor-order.svg" alt="Interceptor in order of HttpClient, AuthInterceptor, AuthInterceptor, HttpBackend, Server, and back in opposite order to show the two-way flow">
|
||||
</div>
|
||||
|
||||
<div class="alert is-helpful">
|
||||
|
@ -857,7 +858,7 @@ The `CachingInterceptor` in the following example demonstrates this approach.
|
|||
* The `isCacheable()` function determines if the request is cacheable.
|
||||
In this sample, only GET requests to the npm package search api are cacheable.
|
||||
|
||||
* If the request is not cacheable, the interceptor simply forwards the request
|
||||
* If the request is not cacheable, the interceptor forwards the request
|
||||
to the next handler in the chain.
|
||||
|
||||
* If a cacheable request is found in the cache, the interceptor returns an `of()` _observable_ with
|
||||
|
|
Loading…
Reference in New Issue