diff --git a/aio/content/examples/toh-pt6/e2e/src/app.e2e-spec.ts b/aio/content/examples/toh-pt6/e2e/src/app.e2e-spec.ts index f9c8b74904..1856368208 100644 --- a/aio/content/examples/toh-pt6/e2e/src/app.e2e-spec.ts +++ b/aio/content/examples/toh-pt6/e2e/src/app.e2e-spec.ts @@ -53,7 +53,7 @@ describe('Tutorial part 6', () => { appDashboardHref: navElts.get(0), appDashboard: element(by.css('app-root app-dashboard')), - topHeroes: element.all(by.css('app-root app-dashboard > div h4')), + topHeroes: element.all(by.css('app-root app-dashboard > div a')), appHeroesHref: navElts.get(1), appHeroes: element(by.css('app-root app-heroes')), @@ -176,7 +176,7 @@ describe('Tutorial part 6', () => { const numHeroes = heroesBefore.length; await element(by.css('input')).sendKeys(addedHeroName); - await element(by.buttonText('add')).click(); + await element(by.buttonText('Add hero')).click(); const page = getPageElts(); const heroesAfter = await toHeroArray(page.allHeroes); @@ -195,18 +195,18 @@ describe('Tutorial part 6', () => { // Inherited styles from styles.css expect(await button.getCssValue('font-family')).toBe('Arial, sans-serif'); expect(await button.getCssValue('border')).toContain('none'); - expect(await button.getCssValue('padding')).toBe('5px 10px'); + expect(await button.getCssValue('padding')).toBe('1px 10px 3px'); expect(await button.getCssValue('border-radius')).toBe('4px'); // Styles defined in heroes.component.css - expect(await button.getCssValue('left')).toBe('194px'); - expect(await button.getCssValue('top')).toBe('-32px'); + expect(await button.getCssValue('left')).toBe('210px'); + expect(await button.getCssValue('top')).toBe('5px'); } - const addButton = element(by.buttonText('add')); + const addButton = element(by.buttonText('Add hero')); // Inherited styles from styles.css expect(await addButton.getCssValue('font-family')).toBe('Arial, sans-serif'); expect(await addButton.getCssValue('border')).toContain('none'); - expect(await addButton.getCssValue('padding')).toBe('5px 10px'); + expect(await addButton.getCssValue('padding')).toBe('8px 24px'); expect(await addButton.getCssValue('border-radius')).toBe('4px'); }); diff --git a/aio/content/examples/toh-pt6/src/app/app.component.css b/aio/content/examples/toh-pt6/src/app/app.component.css index 1bdf7bdd58..114a0b70dd 100644 --- a/aio/content/examples/toh-pt6/src/app/app.component.css +++ b/aio/content/examples/toh-pt6/src/app/app.component.css @@ -1,23 +1,20 @@ /* AppComponent's private CSS styles */ h1 { - font-size: 1.2em; margin-bottom: 0; } nav a { - padding: 5px 10px; + padding: 1rem; text-decoration: none; margin-top: 10px; display: inline-block; - background-color: #eee; + background-color: #e8e8e8; + color: #3d3d3d; border-radius: 4px; } -nav a:visited, a:link { - color: #334953; -} nav a:hover { - color: #039be5; - background-color: #CFD8DC; + color: white; + background-color: #42545C; } nav a.active { - color: #039be5; + background-color: black; } diff --git a/aio/content/examples/toh-pt6/src/app/dashboard/dashboard.component.css b/aio/content/examples/toh-pt6/src/app/dashboard/dashboard.component.css index 031b2e382f..b1e6e6785e 100644 --- a/aio/content/examples/toh-pt6/src/app/dashboard/dashboard.component.css +++ b/aio/content/examples/toh-pt6/src/app/dashboard/dashboard.component.css @@ -1,61 +1,54 @@ /* DashboardComponent's private CSS styles */ -[class*='col-'] { - float: left; - padding-right: 20px; - padding-bottom: 20px; + +h2 { + text-align: center; } -[class*='col-']:last-of-type { - padding-right: 0; + +.heroes-menu { + padding: 0; + margin: auto; + max-width: 1000px; + + /* flexbox */ + display: -webkit-box; + display: -moz-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: space-around; + align-content: flex-start; + align-items: flex-start; } + a { - text-decoration: none; -} -*, *::after, *::before { - box-sizing: border-box; -} -h3 { - text-align: center; - margin-bottom: 0; -} -h4 { - position: relative; -} -.grid { - margin: 0; -} -.col-1-4 { - width: 25%; -} -.module { - padding: 20px; - text-align: center; - color: #eee; - max-height: 120px; - min-width: 120px; background-color: #3f525c; border-radius: 2px; + padding: 1rem; + font-size: 1.2rem; + text-decoration: none; + display: inline-block; + color: #fff; + text-align: center; + width: 100%; + min-width: 70px; + margin: .5rem auto; + box-sizing: border-box; + + /* flexbox */ + order: 0; + flex: 0 1 auto; + align-self: auto; } -.module:hover { - background-color: #EEE; - cursor: pointer; - color: #607d8b; -} -.grid-pad { - padding: 10px 0; -} -.grid-pad > [class*='col-']:last-of-type { - padding-right: 20px; -} -@media (max-width: 600px) { - .module { - font-size: 10px; - max-height: 75px; } -} -@media (max-width: 1024px) { - .grid { - margin: 0; - } - .module { - min-width: 60px; + +@media (min-width: 600px) { + a { + width: 18%; + box-sizing: content-box; } } + +a:hover { + background-color: black; +} diff --git a/aio/content/examples/toh-pt6/src/app/dashboard/dashboard.component.html b/aio/content/examples/toh-pt6/src/app/dashboard/dashboard.component.html index b70c0c7d6e..9a20700f46 100644 --- a/aio/content/examples/toh-pt6/src/app/dashboard/dashboard.component.html +++ b/aio/content/examples/toh-pt6/src/app/dashboard/dashboard.component.html @@ -1,10 +1,8 @@ -

Top Heroes

-
- Top Heroes +
+ -
-

{{hero.name}}

-
+ {{hero.name}}
diff --git a/aio/content/examples/toh-pt6/src/app/dashboard/dashboard.component.spec.ts b/aio/content/examples/toh-pt6/src/app/dashboard/dashboard.component.spec.ts index 224f5db3ce..7fb248d94b 100644 --- a/aio/content/examples/toh-pt6/src/app/dashboard/dashboard.component.spec.ts +++ b/aio/content/examples/toh-pt6/src/app/dashboard/dashboard.component.spec.ts @@ -37,7 +37,7 @@ describe('DashboardComponent', () => { }); it('should display "Top Heroes" as headline', () => { - expect(fixture.nativeElement.querySelector('h3').textContent).toEqual('Top Heroes'); + expect(fixture.nativeElement.querySelector('h2').textContent).toEqual('Top Heroes'); }); it('should call heroService', waitForAsync(() => { diff --git a/aio/content/examples/toh-pt6/src/app/hero-detail/hero-detail.component.css b/aio/content/examples/toh-pt6/src/app/hero-detail/hero-detail.component.css index 6a860b871d..f15f55a449 100644 --- a/aio/content/examples/toh-pt6/src/app/hero-detail/hero-detail.component.css +++ b/aio/content/examples/toh-pt6/src/app/hero-detail/hero-detail.component.css @@ -1,24 +1,19 @@ /* HeroDetailComponent's private CSS styles */ label { - display: inline-block; - width: 3em; - margin: .5em 0; - color: #607D8B; + color: #435960; font-weight: bold; } input { - height: 2em; font-size: 1em; - padding-left: .4em; + padding: .5rem; } button { margin-top: 20px; - font-family: Arial, sans-serif; + margin-right: .5rem; background-color: #eee; - border: none; - padding: 5px 10px; + padding: 1rem; border-radius: 4px; - cursor: pointer; + font-size: 1rem; } button:hover { background-color: #cfd8dc; diff --git a/aio/content/examples/toh-pt6/src/app/hero-detail/hero-detail.component.html b/aio/content/examples/toh-pt6/src/app/hero-detail/hero-detail.component.html index 860378b3b4..dbef138c6d 100644 --- a/aio/content/examples/toh-pt6/src/app/hero-detail/hero-detail.component.html +++ b/aio/content/examples/toh-pt6/src/app/hero-detail/hero-detail.component.html @@ -2,9 +2,8 @@

{{hero.name | uppercase}} Details

id: {{hero.id}}
- + +
diff --git a/aio/content/examples/toh-pt6/src/app/hero-search/hero-search.component.css b/aio/content/examples/toh-pt6/src/app/hero-search/hero-search.component.css index 190d9bbc10..ce919d87f4 100644 --- a/aio/content/examples/toh-pt6/src/app/hero-search/hero-search.component.css +++ b/aio/content/examples/toh-pt6/src/app/hero-search/hero-search.component.css @@ -1,37 +1,45 @@ /* HeroSearch private styles */ -.search-result li { + +label { + display: block; + font-weight: bold; + font-size: 1.2rem; + margin-top: 1rem; + margin-bottom: .5rem; + +} +input { + padding: .5rem; + width: 100%; + max-width: 600px; + box-sizing: border-box; + display: block; +} + +input:focus { + outline: #336699 auto 1px; +} + +li { + list-style-type: none; +} +.search-result li a { border-bottom: 1px solid gray; border-left: 1px solid gray; border-right: 1px solid gray; - width: 195px; - height: 16px; - padding: 5px; - background-color: white; - cursor: pointer; - list-style-type: none; -} - -.search-result li:hover { - background-color: #607D8B; -} - -.search-result li a { - color: #888; - display: block; + display: inline-block; + width: 100%; + max-width: 600px; + padding: .5rem; + box-sizing: border-box; text-decoration: none; + color: black; } .search-result li a:hover { + background-color: #435A60; color: white; } -.search-result li a:active { - color: white; -} -#search-box { - width: 200px; - height: 20px; -} - ul.search-result { margin-top: 0; diff --git a/aio/content/examples/toh-pt6/src/app/hero-search/hero-search.component.html b/aio/content/examples/toh-pt6/src/app/hero-search/hero-search.component.html index de72fd791f..30f649d251 100644 --- a/aio/content/examples/toh-pt6/src/app/hero-search/hero-search.component.html +++ b/aio/content/examples/toh-pt6/src/app/hero-search/hero-search.component.html @@ -1,6 +1,5 @@
-

- + diff --git a/aio/content/examples/toh-pt6/src/app/heroes/heroes.component.css b/aio/content/examples/toh-pt6/src/app/heroes/heroes.component.css index 8e44b7ccda..62760d9fd1 100644 --- a/aio/content/examples/toh-pt6/src/app/heroes/heroes.component.css +++ b/aio/content/examples/toh-pt6/src/app/heroes/heroes.component.css @@ -5,32 +5,44 @@ padding: 0; width: 15em; } + +input { + display: block; + width: 100%; + padding: .5rem; + margin: 1rem 0; + box-sizing: border-box; +} + .heroes li { position: relative; cursor: pointer; - background-color: #EEE; - margin: .5em; - padding: .3em 0; - height: 1.6em; - border-radius: 4px; } .heroes li:hover { - color: #607D8B; - background-color: #DDD; left: .1em; } .heroes a { color: #333; text-decoration: none; - position: relative; + background-color: #EEE; + margin: .5em; + padding: .3em 0; + height: 1.6em; + border-radius: 4px; display: block; - width: 250px; + width: 100%; } .heroes a:hover { - color: #607D8B; + color: #2c3a41; + background-color: #e6e6e6; +} + +.heroes a:active { + background-color: #525252; + color: #fafafa; } .heroes .badge { @@ -38,7 +50,7 @@ font-size: small; color: white; padding: 0.8em 0.7em 0 0.7em; - background-color: #405061; + background-color:#405061; line-height: 1em; position: relative; left: -1px; @@ -50,23 +62,28 @@ 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; +.add-button { + padding: .5rem 1.5rem; + font-size: 1rem; + margin-bottom: 2rem; } -button:hover { - background-color: #cfd8dc; +.add-button:hover { + color: white; + background-color: #42545C; } button.delete { - position: relative; - left: 194px; - top: -32px; - background-color: gray !important; + position: absolute; + left: 210px; + top: 5px; + background-color: white; + color: #525252; + font-size: 1.1rem; + padding: 1px 10px 3px 10px; +} + +button.delete:hover { + background-color: #525252; color: white; } diff --git a/aio/content/examples/toh-pt6/src/app/heroes/heroes.component.html b/aio/content/examples/toh-pt6/src/app/heroes/heroes.component.html index 5daa83bd64..0959a24256 100644 --- a/aio/content/examples/toh-pt6/src/app/heroes/heroes.component.html +++ b/aio/content/examples/toh-pt6/src/app/heroes/heroes.component.html @@ -2,12 +2,12 @@
- + + + -
diff --git a/aio/content/examples/toh-pt6/src/app/messages/messages.component.css b/aio/content/examples/toh-pt6/src/app/messages/messages.component.css index 08585dcbaf..9a914ecbc2 100644 --- a/aio/content/examples/toh-pt6/src/app/messages/messages.component.css +++ b/aio/content/examples/toh-pt6/src/app/messages/messages.component.css @@ -1,20 +1,19 @@ /* MessagesComponent's private CSS styles */ h2 { - color: red; + color: #A80000; font-family: Arial, Helvetica, sans-serif; font-weight: lighter; } -button.clear { - font-family: Arial, sans-serif; +.clear { color: #333; background-color: #eee; margin-bottom: 12px; - border: none; - padding: 5px 10px; + padding: 1rem; border-radius: 4px; - cursor: pointer; + font-size: 1rem; } -button:hover { - background-color: #cfd8dc; +.clear:hover { + color: #fff; + background-color: #42545C; } diff --git a/aio/content/examples/toh-pt6/src/app/messages/messages.component.html b/aio/content/examples/toh-pt6/src/app/messages/messages.component.html index 1df7dfd989..2f0c79464a 100644 --- a/aio/content/examples/toh-pt6/src/app/messages/messages.component.html +++ b/aio/content/examples/toh-pt6/src/app/messages/messages.component.html @@ -2,7 +2,7 @@

Messages

+ (click)="messageService.clear()">Clear messages
{{message}}
diff --git a/aio/content/images/guide/toh/toh-hero-search.gif b/aio/content/images/guide/toh/toh-hero-search.gif new file mode 100644 index 0000000000..dfd50fc3f9 Binary files /dev/null and b/aio/content/images/guide/toh/toh-hero-search.gif differ diff --git a/aio/content/tutorial/toh-pt6.md b/aio/content/tutorial/toh-pt6.md index 3ff79cd566..db086a2e83 100644 --- a/aio/content/tutorial/toh-pt6.md +++ b/aio/content/tutorial/toh-pt6.md @@ -9,7 +9,7 @@ Angular's `HttpClient`.
- For the sample app that this page describes, see the . + For the sample application that this page describes, see the .
@@ -17,7 +17,7 @@ Angular's `HttpClient`. `HttpClient` is Angular's mechanism for communicating with a remote server over HTTP. -Make `HttpClient` available everywhere in the app in two steps. First, add it to the root `AppModule` by importing it: +Make `HttpClient` available everywhere in the application in two steps. First, add it to the root `AppModule` by importing it: @@ -33,7 +33,7 @@ Next, still in the `AppModule`, add `HttpClient` to the `imports` array: This tutorial sample mimics communication with a remote data server by using the [In-memory Web API](https://github.com/angular/angular/tree/master/packages/misc/angular-in-memory-web-api "In-memory Web API") module. -After installing the module, the app will make requests to and receive responses from the `HttpClient` +After installing the module, the application will make requests to and receive responses from the `HttpClient` without knowing that the *In-memory Web API* is intercepting those requests, applying them to an in-memory data store, and returning simulated responses. @@ -127,7 +127,7 @@ Convert that method to use `HttpClient` as follows: Refresh the browser. The hero data should successfully load from the mock server. -You've swapped `of()` for `http.get()` and the app keeps working without any other changes +You've swapped `of()` for `http.get()` and the application keeps working without any other changes because both functions return an `Observable`. ### `HttpClient` methods return one value @@ -197,10 +197,10 @@ has configured with both the name of the operation that failed and a safe return After reporting the error to the console, the handler constructs -a user friendly message and returns a safe value to the app so the app can keep working. +a user friendly message and returns a safe value to the application so the application can keep working. Because each service method returns a different kind of `Observable` result, -`handleError()` takes a type parameter so it can return the safe value as the type that the app expects. +`handleError()` takes a type parameter so it can return the safe value as the type that the application expects. ### Tap into the Observable @@ -283,7 +283,7 @@ The hero now appears in the list with the changed name. ## Add a new hero -To add a hero, this app only needs the hero's name. You can use an `` +To add a hero, this application only needs the hero's name. You can use an `` element paired with an add button. Insert the following into the `HeroesComponent` template, just after @@ -506,7 +506,7 @@ It cancels and discards previous search observables, returning only the latest s Note that canceling a previous `searchHeroes()` Observable doesn't actually abort a pending HTTP request. - Unwanted results are simply discarded before they reach your application code. + Unwanted results are discarded before they reach your application code.
@@ -515,11 +515,11 @@ That's the job of the [`AsyncPipe`](#asyncpipe) in the template. #### Try it -Run the app again. In the *Dashboard*, enter some text in the search box. +Run the application again. In the *Dashboard*, enter some text in the search box. If you enter characters that match any existing hero names, you'll see something like this. ## Final code review