docs: revert Jade to markdown
closes #1818 Previously, the markdown of some chapters was converted to Jade markup to support the conditional exclusion of TS prose parts in Dart chapters. This commit reverts some of that back to clean markdown, thanks to a few custom directives.
This commit is contained in:
parent
e2cd8ffe1d
commit
b0e0d94b5c
|
@ -21,6 +21,7 @@ script(src="https://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular
|
||||||
|
|
||||||
<!-- Angular.io Site JS -->
|
<!-- Angular.io Site JS -->
|
||||||
script(src="/resources/js/site.js")
|
script(src="/resources/js/site.js")
|
||||||
|
script(src="/resources/js/util.js")
|
||||||
script(src="/resources/js/controllers/app-controller.js")
|
script(src="/resources/js/controllers/app-controller.js")
|
||||||
script(src="/resources/js/controllers/resources-controller.js")
|
script(src="/resources/js/controllers/resources-controller.js")
|
||||||
script(src="/resources/js/directives/cheatsheet.js")
|
script(src="/resources/js/directives/cheatsheet.js")
|
||||||
|
@ -32,6 +33,9 @@ script(src="/resources/js/directives/copy.js")
|
||||||
script(src="/resources/js/directives/code-tabs.js")
|
script(src="/resources/js/directives/code-tabs.js")
|
||||||
script(src="/resources/js/directives/code-pane.js")
|
script(src="/resources/js/directives/code-pane.js")
|
||||||
script(src="/resources/js/directives/code-example.js")
|
script(src="/resources/js/directives/code-example.js")
|
||||||
|
script(src="/resources/js/directives/if-docs.js")
|
||||||
|
script(src="/resources/js/directives/live-example.js")
|
||||||
|
script(src="/resources/js/directives/ngio-ex-path.js")
|
||||||
script(src="/resources/js/directives/scroll-y-offset-element.js")
|
script(src="/resources/js/directives/scroll-y-offset-element.js")
|
||||||
|
|
||||||
<!-- GA -->
|
<!-- GA -->
|
||||||
|
|
|
@ -20,12 +20,14 @@ include ../../../_includes/_util-fns
|
||||||
- var _indexHtmlDir = 'web';
|
- var _indexHtmlDir = 'web';
|
||||||
- var _mainDir = 'web';
|
- var _mainDir = 'web';
|
||||||
|
|
||||||
|
//- Deprecated
|
||||||
mixin liveExampleLink(linkText, exampleUrlPartName)
|
mixin liveExampleLink(linkText, exampleUrlPartName)
|
||||||
- var text = linkText || 'live example';
|
- var text = linkText || 'live example';
|
||||||
- var ex = exampleUrlPartName || getExampleName();
|
- var ex = exampleUrlPartName || getExampleName();
|
||||||
- var href = 'http://angular-examples.github.io/' + ex;
|
- var href = 'http://angular-examples.github.io/' + ex;
|
||||||
a(href='#{href}' target="_blank")= text
|
a(href='#{href}' target="_blank")= text
|
||||||
|
|
||||||
|
//- Deprecated
|
||||||
mixin liveExampleLink2(linkText, exampleUrlPartName)
|
mixin liveExampleLink2(linkText, exampleUrlPartName)
|
||||||
- var srcText = attributes.srcText || 'view source';
|
- var srcText = attributes.srcText || 'view source';
|
||||||
- var ex = exampleUrlPartName || attributes.example || getExampleName();
|
- var ex = exampleUrlPartName || attributes.example || getExampleName();
|
||||||
|
|
|
@ -10,21 +10,12 @@ block ctor-syntax
|
||||||
We also leveraged Dart's constructor syntax for declaring parameters and
|
We also leveraged Dart's constructor syntax for declaring parameters and
|
||||||
initializing properties simultaneously.
|
initializing properties simultaneously.
|
||||||
|
|
||||||
block service-in-its-own-file
|
|
||||||
//- N/A
|
|
||||||
|
|
||||||
block one-class-per-file-ts-tradeoffs
|
|
||||||
//- N/A
|
|
||||||
|
|
||||||
block injectable-not-always-needed-in-ts
|
block injectable-not-always-needed-in-ts
|
||||||
//- The [Angular 2 Dart Transformer](https://github.com/angular/angular/wiki/Angular-2-Dart-Transformer)
|
//- The [Angular 2 Dart Transformer](https://github.com/angular/angular/wiki/Angular-2-Dart-Transformer)
|
||||||
//- generates static code to replace the use of dart:mirrors. It requires that types be
|
//- generates static code to replace the use of dart:mirrors. It requires that types be
|
||||||
//- identified as targets for static code generation. Generally this is achieved
|
//- identified as targets for static code generation. Generally this is achieved
|
||||||
//- by marking the class as @Injectable (though there are other mechanisms).
|
//- by marking the class as @Injectable (though there are other mechanisms).
|
||||||
|
|
||||||
block ts-any-decorator-will-do
|
|
||||||
//- N/A
|
|
||||||
|
|
||||||
block always-include-paren
|
block always-include-paren
|
||||||
:marked
|
:marked
|
||||||
Always write `@Injectable()`, not just `@Injectable`.
|
Always write `@Injectable()`, not just `@Injectable`.
|
||||||
|
@ -43,11 +34,6 @@ block real-logger
|
||||||
A real implementation would probably use the
|
A real implementation would probably use the
|
||||||
[logging package](https://pub.dartlang.org/packages/logging).
|
[logging package](https://pub.dartlang.org/packages/logging).
|
||||||
|
|
||||||
block canonical-provider-expr
|
|
||||||
| that creates a new instance of the
|
|
||||||
a(href="../api/core/Provider-class.html") Provider
|
|
||||||
| class:
|
|
||||||
|
|
||||||
block provider-ctor-args
|
block provider-ctor-args
|
||||||
- var _secondParam = 'named parameter, such as <code>useClass</code>'
|
- var _secondParam = 'named parameter, such as <code>useClass</code>'
|
||||||
:marked
|
:marked
|
||||||
|
|
|
@ -8,16 +8,9 @@ block includes
|
||||||
- var _Angular_http_library = 'Dart <a href="' + _httpUrl + '"><b>http</b></a> library'
|
- var _Angular_http_library = 'Dart <a href="' + _httpUrl + '"><b>http</b></a> library'
|
||||||
|
|
||||||
block demos-list
|
block demos-list
|
||||||
li #[a(href="#http-client") HTTP client: Tour of Heroes]
|
:marked
|
||||||
li #[a(href="#cors") JSONP client: Wikipedia to fetch data from a service that does not support CORS] #[b (under development)]
|
- [HTTP client: Tour of Heroes](#http-client)
|
||||||
|
- [JSONP client: Wikipedia to fetch data from a service that does not support CORS (**under development**)](#cors)
|
||||||
block rxjs-import
|
|
||||||
//- N/A
|
|
||||||
|
|
||||||
block http-client
|
|
||||||
|
|
||||||
block system-config-of-http
|
|
||||||
//- N/A
|
|
||||||
|
|
||||||
block http-providers
|
block http-providers
|
||||||
:marked
|
:marked
|
||||||
|
@ -50,9 +43,6 @@ block getheroes-and-addhero
|
||||||
programming in Dart, or the tutorial on
|
programming in Dart, or the tutorial on
|
||||||
[_Asynchronous Programming: Futures_](https://www.dartlang.org/docs/tutorials/futures/).
|
[_Asynchronous Programming: Futures_](https://www.dartlang.org/docs/tutorials/futures/).
|
||||||
|
|
||||||
block rxjs
|
|
||||||
//- N/A
|
|
||||||
|
|
||||||
block parse-json
|
block parse-json
|
||||||
:marked
|
:marked
|
||||||
The response data are in JSON string form.
|
The response data are in JSON string form.
|
||||||
|
@ -65,7 +55,7 @@ block error-handling
|
||||||
block hlc-error-handling
|
block hlc-error-handling
|
||||||
:marked
|
:marked
|
||||||
Back in the `HeroListComponent`, we wrapped our call to
|
Back in the `HeroListComponent`, we wrapped our call to
|
||||||
`#{_priv}heroService.getHeroes()` in a `try` clause. When an exception is
|
`!{_priv}heroService.getHeroes()` in a `try` clause. When an exception is
|
||||||
caught, the `errorMessage` variable — which we've bound conditionally in the
|
caught, the `errorMessage` variable — which we've bound conditionally in the
|
||||||
template — gets assigned to.
|
template — gets assigned to.
|
||||||
|
|
||||||
|
@ -75,9 +65,6 @@ block hero-list-comp-add-hero
|
||||||
awaits for the *service's* asynchronous `addHero()` to return, and when it does,
|
awaits for the *service's* asynchronous `addHero()` to return, and when it does,
|
||||||
the new hero is added to the `heroes` list for presentation to the user.
|
the new hero is added to the `heroes` list for presentation to the user.
|
||||||
|
|
||||||
block promises
|
|
||||||
//- N/A
|
|
||||||
|
|
||||||
block wikipedia-jsonp+
|
block wikipedia-jsonp+
|
||||||
:marked
|
:marked
|
||||||
Wikipedia offers a modern `CORS` API and a legacy `JSONP` search API.
|
Wikipedia offers a modern `CORS` API and a legacy `JSONP` search API.
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
include ../_util-fns
|
include ../_util-fns
|
||||||
|
|
||||||
+includeShared('{ts}', 'intro')
|
+includeShared('{ts}', 'intro')
|
||||||
|
|
||||||
p Run the #[+liveExampleLink2('', 'toh-5')].
|
|
||||||
|
|
||||||
+includeShared('{ts}', 'main')
|
+includeShared('{ts}', 'main')
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,8 @@ include ../_util-fns
|
||||||
|
|
||||||
.callout.is-helpful
|
.callout.is-helpful
|
||||||
header Source code
|
header Source code
|
||||||
p Run the #[+liveExampleLink2('', 'toh-1')] for this part.
|
:marked
|
||||||
|
Run the <live-example></live-example> for this part.
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
## Keep the app compiling and running
|
## Keep the app compiling and running
|
||||||
|
|
|
@ -6,8 +6,8 @@ include ../_util-fns
|
||||||
We’ll expand our Tour of Heroes app to display a list of heroes,
|
We’ll expand our Tour of Heroes app to display a list of heroes,
|
||||||
allow the user to select a hero, and display the hero’s details.
|
allow the user to select a hero, and display the hero’s details.
|
||||||
|
|
||||||
p Run the #[+liveExampleLink2('', 'toh-2')] for this part.
|
Run the <live-example></live-example> for this part.
|
||||||
:marked
|
|
||||||
Let’s take stock of what we’ll need to display a list of heroes.
|
Let’s take stock of what we’ll need to display a list of heroes.
|
||||||
First, we need a list of heroes. We want to display those heroes in the view’s template,
|
First, we need a list of heroes. We want to display those heroes in the view’s template,
|
||||||
so we’ll need a way to do that.
|
so we’ll need a way to do that.
|
||||||
|
@ -294,8 +294,8 @@ code-example(language="bash").
|
||||||
* We added the ability to select a hero and show the hero’s details
|
* We added the ability to select a hero and show the hero’s details
|
||||||
* We learned how to use the built-in directives `ngIf` and `ngFor` in a component’s template
|
* We learned how to use the built-in directives `ngIf` and `ngFor` in a component’s template
|
||||||
|
|
||||||
p Run the #[+liveExampleLink2('', 'toh-2')] for this part.
|
Run the <live-example></live-example> for this part.
|
||||||
:marked
|
|
||||||
### The Road Ahead
|
### The Road Ahead
|
||||||
Our Tour of Heroes has grown, but it’s far from complete.
|
Our Tour of Heroes has grown, but it’s far from complete.
|
||||||
We can't put the entire app into a single component.
|
We can't put the entire app into a single component.
|
||||||
|
|
|
@ -4,7 +4,7 @@ include ../_util-fns
|
||||||
Our app is growing.
|
Our app is growing.
|
||||||
Use cases are flowing in for reusing components, passing data to components, and creating more reusable assets. Let's separate the heroes list from the hero details and make the details component reusable.
|
Use cases are flowing in for reusing components, passing data to components, and creating more reusable assets. Let's separate the heroes list from the hero details and make the details component reusable.
|
||||||
|
|
||||||
p Run the #[+liveExampleLink2('', 'toh-3')] for this part.
|
Run the <live-example></live-example> for this part.
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
|
@ -240,7 +240,7 @@ code-example(format=".")
|
||||||
* We learned to bind a parent component to a child component.
|
* We learned to bind a parent component to a child component.
|
||||||
* We learned to declare the application directives we need in a `directives` list.
|
* We learned to declare the application directives we need in a `directives` list.
|
||||||
|
|
||||||
p Run the #[+liveExampleLink2('', 'toh-3')] for this part.
|
Run the <live-example></live-example> for this part.
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
|
|
|
@ -15,7 +15,7 @@ include ../_util-fns
|
||||||
Because data services are invariably asynchronous,
|
Because data services are invariably asynchronous,
|
||||||
we'll finish the chapter with a **!{_Promise}**-based version of the data service.
|
we'll finish the chapter with a **!{_Promise}**-based version of the data service.
|
||||||
|
|
||||||
p Run the #[+liveExampleLink2('', 'toh-4')] for this part.
|
Run the <live-example></live-example> for this part.
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
|
|
|
@ -18,7 +18,7 @@ figure.image-display
|
||||||
The [Routing and Navigation](../guide/router.html) chapter covers the router in more detail
|
The [Routing and Navigation](../guide/router.html) chapter covers the router in more detail
|
||||||
than we will in this tutorial.
|
than we will in this tutorial.
|
||||||
|
|
||||||
p Run the #[+liveExampleLink2('', 'toh-5')] for this part.
|
Run the <live-example></live-example> for this part.
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
|
@ -653,11 +653,10 @@ figure.image-display
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
## Application structure and code
|
## Application structure and code
|
||||||
p.
|
|
||||||
Review the sample source code in the #[+liveExampleLink2('', 'toh-5')] for this chapter.
|
Review the sample source code in the <live-example></live-example> for this chapter.
|
||||||
Verify that we have the following structure:
|
Verify that we have the following structure:
|
||||||
|
|
||||||
:marked
|
|
||||||
.filetree
|
.filetree
|
||||||
.file angular2_tour_of_heroes
|
.file angular2_tour_of_heroes
|
||||||
.children
|
.children
|
||||||
|
|
|
@ -4,12 +4,14 @@ include ../../../_includes/_util-fns
|
||||||
- var _docsFor = 'ts';
|
- var _docsFor = 'ts';
|
||||||
//- Other values match the defaults.
|
//- Other values match the defaults.
|
||||||
|
|
||||||
|
//- Deprecated
|
||||||
mixin liveExampleLink(linkText, exampleUrlPartName)
|
mixin liveExampleLink(linkText, exampleUrlPartName)
|
||||||
- var text = linkText || 'live example';
|
- var text = linkText || 'live example';
|
||||||
- var ex = exampleUrlPartName || getExampleName();
|
- var ex = exampleUrlPartName || getExampleName();
|
||||||
- var href = '/resources/live-examples/' + ex + '/ts/plnkr.html';
|
- var href = '/resources/live-examples/' + ex + '/ts/plnkr.html';
|
||||||
a(href='#{href}' target="_blank")= text
|
a(href='#{href}' target="_blank")= text
|
||||||
|
|
||||||
|
//- Deprecated
|
||||||
mixin liveExampleLink2(linkText, exampleUrlPartName)
|
mixin liveExampleLink2(linkText, exampleUrlPartName)
|
||||||
//- In Dart this gives 2 links: to the demo and to the source.
|
//- In Dart this gives 2 links: to the demo and to the source.
|
||||||
+liveExampleLink(linkText, exampleUrlPartName)
|
+liveExampleLink(linkText, exampleUrlPartName)
|
||||||
|
|
|
@ -11,9 +11,8 @@ block includes
|
||||||
* [respond to user-initiated events](#respond-to-user)
|
* [respond to user-initiated events](#respond-to-user)
|
||||||
* [pass values into the directive using data binding](#bindings)
|
* [pass values into the directive using data binding](#bindings)
|
||||||
|
|
||||||
p Try the #[+liveExampleLink2()].
|
Try the <live-example></live-example>.
|
||||||
|
|
||||||
:marked
|
|
||||||
## Directives overview
|
## Directives overview
|
||||||
|
|
||||||
There are three kinds of directives in Angular:
|
There are three kinds of directives in Angular:
|
||||||
|
|
|
@ -20,7 +20,7 @@ block includes
|
||||||
* [Appendix 1: Inspecting the generated runtime component styles](#inspect-generated-css)
|
* [Appendix 1: Inspecting the generated runtime component styles](#inspect-generated-css)
|
||||||
* [Appendix 2: Loading Styles with Relative URLs](#relative-urls)
|
* [Appendix 2: Loading Styles with Relative URLs](#relative-urls)
|
||||||
|
|
||||||
p Run the #[+liveExampleLink2()] of the code shown in this chapter.
|
Run the <live-example></live-example> of the code shown in this chapter.
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
|
|
|
@ -17,7 +17,7 @@ block includes
|
||||||
- [Dependency injection tokens](#dependency-injection-tokens)
|
- [Dependency injection tokens](#dependency-injection-tokens)
|
||||||
- [Summary](#summary)
|
- [Summary](#summary)
|
||||||
|
|
||||||
p Run the #[+liveExampleLink2()].
|
Run the <live-example></live-example>.
|
||||||
|
|
||||||
.l-main-section#why-di
|
.l-main-section#why-di
|
||||||
:marked
|
:marked
|
||||||
|
@ -427,7 +427,7 @@ block injectable-not-always-needed-in-ts
|
||||||
fact `InjectableMetadata` #{_decorator}s that
|
fact `InjectableMetadata` #{_decorator}s that
|
||||||
identify a class as a target for instantiation by an injector.
|
identify a class as a target for instantiation by an injector.
|
||||||
|
|
||||||
block ts-any-decorator-will-do
|
+ifDocsFor('ts')
|
||||||
.l-sub-section
|
.l-sub-section
|
||||||
:marked
|
:marked
|
||||||
Injectors use a class's constructor metadata to determine dependent types as
|
Injectors use a class's constructor metadata to determine dependent types as
|
||||||
|
@ -508,20 +508,25 @@ code-example(format="nocode").
|
||||||
What matters is that the injector has a provider to go to when it needs a `Logger`.
|
What matters is that the injector has a provider to go to when it needs a `Logger`.
|
||||||
|
|
||||||
//- Dart limitation: the provide function isn't const so it cannot be used in an annotation.
|
//- Dart limitation: the provide function isn't const so it cannot be used in an annotation.
|
||||||
- var __andProvideFn = _docsFor == 'dart' ? '' : 'and <i>provide</i> object literal';
|
- var _andProvideFn = _docsFor == 'dart' ? '' : 'and <i>provide</i> object literal';
|
||||||
#provide
|
#provide
|
||||||
:marked
|
:marked
|
||||||
### The *Provider* class !{__andProvideFn}
|
### The *Provider* class !{_andProvideFn}
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
We wrote the `providers` #{_array} like this:
|
We wrote the `providers` #{_array} like this:
|
||||||
|
|
||||||
+makeExample('dependency-injection/ts/app/providers.component.ts','providers-1')
|
+makeExample('dependency-injection/ts/app/providers.component.ts','providers-1')
|
||||||
|
|
||||||
p
|
:marked
|
||||||
| This is actually a short-hand expression for a provider registration
|
This is actually a short-hand expression for a provider registration
|
||||||
block canonical-provider-expr
|
<span if-docs="ts">
|
||||||
| using a <i>provider</i> object literal with two properties:
|
using a _provider_ object literal with two properties:
|
||||||
|
</span>
|
||||||
|
<span if-docs="dart">
|
||||||
|
that creates a new instance of the
|
||||||
|
[Provider](../api/core/Provider-class.html) class:
|
||||||
|
</span>
|
||||||
|
|
||||||
+makeExample('dependency-injection/ts/app/providers.component.ts','providers-3')
|
+makeExample('dependency-injection/ts/app/providers.component.ts','providers-3')
|
||||||
|
|
||||||
|
@ -861,7 +866,7 @@ block dart-map-alternative
|
||||||
Framework developers may take this approach when they
|
Framework developers may take this approach when they
|
||||||
must acquire services generically and dynamically.
|
must acquire services generically and dynamically.
|
||||||
|
|
||||||
block one-class-per-file-ts-tradeoffs
|
+ifDocsFor('ts')
|
||||||
.l-main-section#one-class-per-file
|
.l-main-section#one-class-per-file
|
||||||
:marked
|
:marked
|
||||||
## Appendix: Why we recommend one class per file
|
## Appendix: Why we recommend one class per file
|
||||||
|
|
|
@ -13,7 +13,7 @@ block includes
|
||||||
|
|
||||||
In this chapter we explore these points and write some code.
|
In this chapter we explore these points and write some code.
|
||||||
|
|
||||||
p Try the #[+liveExampleLink2()].
|
Try the <live-example></live-example>.
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
|
|
|
@ -24,7 +24,7 @@ block includes
|
||||||
* [AfterViewInit and AfterViewChecked](#afterview)
|
* [AfterViewInit and AfterViewChecked](#afterview)
|
||||||
* [AfterContentInit and AfterContentChecked](#aftercontent)
|
* [AfterContentInit and AfterContentChecked](#aftercontent)
|
||||||
|
|
||||||
p Try the #[+liveExampleLink2()].
|
Try the <live-example></live-example>.
|
||||||
|
|
||||||
a#hooks-overview
|
a#hooks-overview
|
||||||
.l-main-section
|
.l-main-section
|
||||||
|
@ -195,14 +195,14 @@ a(id="other-lifecycles")
|
||||||
3rd party libraries might implement their hooks as well in order to give us, the developers, more
|
3rd party libraries might implement their hooks as well in order to give us, the developers, more
|
||||||
control over how these libraries are used.
|
control over how these libraries are used.
|
||||||
|
|
||||||
a#the-sample
|
.l-main-section#the-sample
|
||||||
.l-main-section
|
:marked
|
||||||
h2 Lifecycle exercises
|
## Lifecycle exercises
|
||||||
p.
|
|
||||||
The #[+liveExampleLink()]
|
The <live-example></live-example>
|
||||||
demonstrates the lifecycle hooks in action through a series of exercises
|
demonstrates the lifecycle hooks in action through a series of exercises
|
||||||
presented as components under the control of the root `AppComponent`.
|
presented as components under the control of the root `AppComponent`.
|
||||||
:marked
|
|
||||||
They follow a common pattern: a *parent* component serves as a test rig for
|
They follow a common pattern: a *parent* component serves as a test rig for
|
||||||
a *child* component that illustrates one or more of the lifecycle hook methods.
|
a *child* component that illustrates one or more of the lifecycle hook methods.
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,9 @@ block includes
|
||||||
desire many of the same transformations repeatedly, both within and across many applications.
|
desire many of the same transformations repeatedly, both within and across many applications.
|
||||||
We almost think of them as styles.
|
We almost think of them as styles.
|
||||||
In fact, we'd like to apply them in our HTML templates as we do styles.
|
In fact, we'd like to apply them in our HTML templates as we do styles.
|
||||||
p.
|
|
||||||
Introducing Angular pipes, a way to write display-value transformations that we can declare in our HTML!
|
Introducing Angular pipes, a way to write display-value transformations that we can declare in our HTML!
|
||||||
Try the #[+liveExampleLink2()].
|
Try the <live-example></live-example>.
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
|
@ -168,11 +168,10 @@ figure.image-display
|
||||||
Angular built-in pipes are pre-registered.
|
Angular built-in pipes are pre-registered.
|
||||||
Custom pipes must be registered manually.
|
Custom pipes must be registered manually.
|
||||||
|
|
||||||
p.
|
:marked
|
||||||
If we try the #[+liveExampleLink()],
|
If we try the <live-example></live-example>,
|
||||||
we can probe its behavior by changing the value and the optional exponent in the template.
|
we can probe its behavior by changing the value and the optional exponent in the template.
|
||||||
|
|
||||||
:marked
|
|
||||||
## Power Boost Calculator (extra-credit)
|
## Power Boost Calculator (extra-credit)
|
||||||
|
|
||||||
It's not much fun updating the template to test our custom pipe.
|
It's not much fun updating the template to test our custom pipe.
|
||||||
|
@ -219,10 +218,10 @@ a#change-detection
|
||||||
Here's the `FlyingHeroesPipe` implementation which follows the pattern for custom pipes we saw earlier.
|
Here's the `FlyingHeroesPipe` implementation which follows the pattern for custom pipes we saw earlier.
|
||||||
+makeExample('pipes/ts/app/flying-heroes.pipe.ts', 'pure', 'app/flying-heroes.pipe.ts')(format='.')
|
+makeExample('pipes/ts/app/flying-heroes.pipe.ts', 'pure', 'app/flying-heroes.pipe.ts')(format='.')
|
||||||
|
|
||||||
p.
|
|
||||||
When we run the sample now we see odd behavior (try it in the #[+liveExampleLink()]).
|
|
||||||
Every hero we add is a flying hero but none of them are displayed.
|
|
||||||
:marked
|
:marked
|
||||||
|
When we run the sample now we see odd behavior (try it in the <live-example></live-example>).
|
||||||
|
Every hero we add is a flying hero but none of them are displayed.
|
||||||
|
|
||||||
Although we're not getting the behavior we want, Angular isn't broken.
|
Although we're not getting the behavior we want, Angular isn't broken.
|
||||||
It's just using a different change detection algorithm — one that ignores changes to the list or any of its items.
|
It's just using a different change detection algorithm — one that ignores changes to the list or any of its items.
|
||||||
|
|
||||||
|
@ -328,11 +327,10 @@ block pure-change
|
||||||
|
|
||||||
We can derive a `FlyingHeroesImpureComponent` that we derive from the `FlyingHeroesComponent`.
|
We can derive a `FlyingHeroesImpureComponent` that we derive from the `FlyingHeroesComponent`.
|
||||||
+makeExample('pipes/ts/app/flying-heroes.component.ts','impure-component','app/flying-heroes.component.ts (FlyingHeroesImpureComponent)')(format='.')
|
+makeExample('pipes/ts/app/flying-heroes.component.ts','impure-component','app/flying-heroes.component.ts (FlyingHeroesImpureComponent)')(format='.')
|
||||||
p.
|
:marked
|
||||||
The only substantive change is the pipe.
|
The only substantive change is the pipe.
|
||||||
We can confirm in the #[+liveExampleLink()] that the #[i flying heroes]
|
We can confirm in the <live-example></live-example> that the _flying heroes_
|
||||||
display updates as we enter new heroes even when we mutate the
|
display updates as we enter new heroes even when we mutate the `heroes` #{_array}.
|
||||||
#[code heroes] #{_array}.
|
|
||||||
|
|
||||||
- var _dollar = _docsFor === 'ts' ? '$' : '';
|
- var _dollar = _docsFor === 'ts' ? '$' : '';
|
||||||
h3#async-pipe The impure #[i AsyncPipe]
|
h3#async-pipe The impure #[i AsyncPipe]
|
||||||
|
|
|
@ -20,7 +20,7 @@ block includes
|
||||||
* [HTTP-level Vulnerabilities](#http)
|
* [HTTP-level Vulnerabilities](#http)
|
||||||
* [Auditing Angular Applications](#code-review)
|
* [Auditing Angular Applications](#code-review)
|
||||||
|
|
||||||
p Try the #[+liveExampleLink2()] of the code shown in this chapter.
|
Try the <live-example></live-example> of the code shown in this chapter.
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
h2#report-issues Reporting Vulnerabilities
|
h2#report-issues Reporting Vulnerabilities
|
||||||
|
|
|
@ -19,41 +19,41 @@ block includes
|
||||||
The !{_Angular_http_library} simplifies application programming of the **XHR** and **JSONP** APIs
|
The !{_Angular_http_library} simplifies application programming of the **XHR** and **JSONP** APIs
|
||||||
as we'll learn in this chapter covering:
|
as we'll learn in this chapter covering:
|
||||||
|
|
||||||
ul
|
- [HTTP client sample overview](#http-client)
|
||||||
li #[a(href="#http-client") HTTP client sample overview]
|
- [Fetch data with http.get](#fetch-data)
|
||||||
li #[a(href="#fetch-data") Fetch data with http.get]
|
<li if-docs="ts"> [RxJS Observable of HTTP Responses](#rxjs)</li>
|
||||||
+ifDocsFor('ts')
|
<li if-docs="ts"> [Enabling RxJS Operators](#enable-rxjs-operators)</li>
|
||||||
li #[a(href="#rxjs") RxJS Observable of HTTP Responses]
|
- [Extract JSON data](#extract-data)
|
||||||
li #[a(href="#enable-rxjs-operators") Enabling RxJS Operators]
|
- [Error handling](#error-handling)
|
||||||
li #[a(href="#extract-data") Extract JSON data]
|
- [Send data to the server](#update)
|
||||||
li #[a(href="#error-handling") Error handling]
|
<li if-docs="ts"> [Promises instead of observables](#promises)</li>
|
||||||
li #[a(href="#update") Send data to the server]
|
- [Cross-origin requests: Wikipedia example](#cors)
|
||||||
+ifDocsFor('ts')
|
<ul if-docs="ts">
|
||||||
li #[a(href="#promises") Promises instead of observables]
|
<li> [Set query string parameters](#search-parameters)</li>
|
||||||
li #[a(href="#cors") Cross-origin requests: Wikipedia example]
|
<li> [Debounce search term input](#more-observables)</li>
|
||||||
+ifDocsFor('ts')
|
</ul>
|
||||||
ul
|
- [Appendix: the in-memory web api service](#in-mem-web-api)
|
||||||
li #[a(href="#search-parameters") Set query string parameters]
|
|
||||||
li #[a(href="#more-observables") Debounce search term input]
|
We illustrate these topics with code that you can <live-example>run live</live-example>.
|
||||||
li #[a(href="#in-mem-web-api") Appendix: the in-memory web api service]
|
|
||||||
p.
|
|
||||||
We illustrate these topics with code that you can
|
|
||||||
#[+liveExampleLink2('run live in a browser')].
|
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
h1 Demos
|
:marked
|
||||||
p This chapter describes server communication with the help of the following demos
|
# Demos
|
||||||
ul
|
|
||||||
block demos-list
|
This chapter describes server communication with the help of the following demos
|
||||||
li #[a(href="#http-client") HTTP client: Tour of Heroes with Observables]
|
|
||||||
li #[a(href="#promises") HTTP client: Tour of Heroes with #{_Promise}s]
|
block demos-list
|
||||||
li #[a(href="#cors") JSONP client: Wikipedia to fetch data from a service that does not support CORS]
|
:marked
|
||||||
li #[a(href="#more-observables") JSONP client: Wikipedia using observable operators to reduce server calls]
|
- [HTTP client: Tour of Heroes with Observables](#http-client)
|
||||||
|
- [HTTP client: Tour of Heroes with !{_Promise}s](#promises)
|
||||||
|
- [JSONP client: Wikipedia to fetch data from a service that does not support CORS](#cors)
|
||||||
|
- [JSONP client: Wikipedia using observable operators to reduce server calls](#more-observables)
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
These demos are orchestrated by the root `AppComponent`
|
These demos are orchestrated by the root `AppComponent`
|
||||||
+makeExample('server-communication/ts/app/app.component.ts', null, 'app/app.component.ts')
|
+makeExample('server-communication/ts/app/app.component.ts', null, 'app/app.component.ts')
|
||||||
|
|
||||||
block rxjs-import
|
+ifDocsFor('ts')
|
||||||
:marked
|
:marked
|
||||||
There is nothing remarkable here _except_ for the import of RxJS operators.
|
There is nothing remarkable here _except_ for the import of RxJS operators.
|
||||||
+makeExample('server-communication/ts/app/app.component.ts', 'import-rxjs')(format='.')
|
+makeExample('server-communication/ts/app/app.component.ts', 'import-rxjs')(format='.')
|
||||||
|
@ -62,23 +62,30 @@ block rxjs-import
|
||||||
:marked
|
:marked
|
||||||
First, we have to configure our application to use server communication facilities.
|
First, we have to configure our application to use server communication facilities.
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section#http-providers
|
||||||
h1#http-providers Providing HTTP Services
|
|
||||||
:marked
|
:marked
|
||||||
|
# Providing HTTP Services
|
||||||
|
|
||||||
We use the !{_Angular_Http} client to communicate with a server using a familiar HTTP request/response protocol.
|
We use the !{_Angular_Http} client to communicate with a server using a familiar HTTP request/response protocol.
|
||||||
The `#{_Http}` client is one of a family of services in the !{_Angular_http_library}.
|
The `!{_Http}` client is one of a family of services in the !{_Angular_http_library}.
|
||||||
block system-config-of-http
|
|
||||||
|
+ifDocsFor('ts')
|
||||||
.l-sub-section
|
.l-sub-section
|
||||||
:marked
|
:marked
|
||||||
SystemJS knows how to load services from the !{_Angular_http_library} when we import from the `@angular/http` module
|
SystemJS knows how to load services from the !{_Angular_http_library} when we import from the `@angular/http` module
|
||||||
because we registered that module name in the `system.config` file.
|
because we registered that module name in the `system.config` file.
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
Before we can use the `#{_Http}` client , we'll have to register it as a service provider with the Dependency Injection system.
|
Before we can use the `!{_Http}` client , we'll have to register it as a service provider with the Dependency Injection system.
|
||||||
|
|
||||||
.l-sub-section
|
.l-sub-section
|
||||||
:marked
|
:marked
|
||||||
Learn about providers in the [Dependency Injection](dependency-injection.html) chapter.
|
Learn about providers in the [Dependency Injection](dependency-injection.html) chapter.
|
||||||
|
|
||||||
p In this demo, we register providers in the #[code bootstrap] method of #[code #[+adjExPath('app/main.ts')]].
|
:marked
|
||||||
|
In this demo, we register providers in the `bootstrap()` method of
|
||||||
|
<span ngio-ex>app/main.ts</span>.
|
||||||
|
|
||||||
+makeExample('server-communication/ts/app/main.ts', 'v1', 'app/main.ts (v1)')(format='.')
|
+makeExample('server-communication/ts/app/main.ts', 'v1', 'app/main.ts (v1)')(format='.')
|
||||||
|
|
||||||
block http-providers
|
block http-providers
|
||||||
|
@ -104,9 +111,10 @@ block http-providers
|
||||||
Such sleight-of-hand is something the root application component should *not* know about.
|
Such sleight-of-hand is something the root application component should *not* know about.
|
||||||
For this reason, and this reason *only*, we hide it *above* the `AppComponent` in `main.ts`.
|
For this reason, and this reason *only*, we hide it *above* the `AppComponent` in `main.ts`.
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section#http-client
|
||||||
h1#http-client The Tour of Heroes #[i HTTP] Client Demo
|
|
||||||
:marked
|
:marked
|
||||||
|
# The Tour of Heroes _HTTP_ Client Demo
|
||||||
|
|
||||||
Our first demo is a mini-version of the [tutorial](../tutorial)'s "Tour of Heroes" (ToH) application.
|
Our first demo is a mini-version of the [tutorial](../tutorial)'s "Tour of Heroes" (ToH) application.
|
||||||
This version gets some heroes from the server, displays them in a list, lets us add new heroes, and saves them to the server.
|
This version gets some heroes from the server, displays them in a list, lets us add new heroes, and saves them to the server.
|
||||||
We use the !{_Angular_Http} client to communicate via `XMLHttpRequest (XHR)`.
|
We use the !{_Angular_Http} client to communicate via `XMLHttpRequest (XHR)`.
|
||||||
|
@ -168,10 +176,11 @@ block getheroes-and-addhero
|
||||||
:marked
|
:marked
|
||||||
With our basic intuitions about the component squared away, we're ready to look inside the `HeroService`.
|
With our basic intuitions about the component squared away, we're ready to look inside the `HeroService`.
|
||||||
|
|
||||||
.l-main-section
|
|
||||||
a#HeroService
|
a#HeroService
|
||||||
h2#fetch-data Fetch data with the #[b HeroService]
|
.l-main-section#fetch-data
|
||||||
:marked
|
:marked
|
||||||
|
## Fetch data with the **HeroService**
|
||||||
|
|
||||||
In many of our previous samples we faked the interaction with the server by
|
In many of our previous samples we faked the interaction with the server by
|
||||||
returning mock heroes in a service like this one:
|
returning mock heroes in a service like this one:
|
||||||
+makeExample('toh-4/ts/app/hero.service.ts', 'just-get-heroes')(format=".")
|
+makeExample('toh-4/ts/app/hero.service.ts', 'just-get-heroes')(format=".")
|
||||||
|
@ -184,7 +193,7 @@ h2#fetch-data Fetch data with the #[b HeroService]
|
||||||
[injected](dependency-injection.html) into the `HeroService` constructor.
|
[injected](dependency-injection.html) into the `HeroService` constructor.
|
||||||
+makeExample('server-communication/ts/app/toh/hero.service.ts', 'ctor')
|
+makeExample('server-communication/ts/app/toh/hero.service.ts', 'ctor')
|
||||||
:marked
|
:marked
|
||||||
Look closely at how we call `#{_priv}http.get`
|
Look closely at how we call `!{_priv}http.get`
|
||||||
+makeExample('server-communication/ts/app/toh/hero.service.ts', 'http-get', 'app/toh/hero.service.ts (getHeroes)')(format=".")
|
+makeExample('server-communication/ts/app/toh/hero.service.ts', 'http-get', 'app/toh/hero.service.ts (getHeroes)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
We pass the resource URL to `get` and it calls the server which should return heroes.
|
We pass the resource URL to `get` and it calls the server which should return heroes.
|
||||||
|
@ -195,7 +204,7 @@ h2#fetch-data Fetch data with the #[b HeroService]
|
||||||
Alternatively, we can (temporarily) target a JSON file by changing the endpoint URL:
|
Alternatively, we can (temporarily) target a JSON file by changing the endpoint URL:
|
||||||
+makeExample('server-communication/ts/app/toh/hero.service.ts', 'endpoint-json')(format=".")
|
+makeExample('server-communication/ts/app/toh/hero.service.ts', 'endpoint-json')(format=".")
|
||||||
|
|
||||||
block rxjs
|
+ifDocsFor('ts')
|
||||||
:marked
|
:marked
|
||||||
<a id="rxjs"></a>
|
<a id="rxjs"></a>
|
||||||
The return value may surprise us.
|
The return value may surprise us.
|
||||||
|
@ -253,7 +262,7 @@ l-main-section
|
||||||
a#extract-data
|
a#extract-data
|
||||||
:marked
|
:marked
|
||||||
## Process the response object
|
## Process the response object
|
||||||
Remember that our `getHeroes()` method mapped the `#{_priv}http.get` response object to heroes with an `#{_priv}extractData` helper method:
|
Remember that our `getHeroes()` method mapped the `!{_priv}http.get` response object to heroes with an `!{_priv}extractData` helper method:
|
||||||
+makeExample('server-communication/ts/app/toh/hero.service.ts', 'extract-data', 'app/toh/hero.service.ts (excerpt)')(format=".")
|
+makeExample('server-communication/ts/app/toh/hero.service.ts', 'extract-data', 'app/toh/hero.service.ts (excerpt)')(format=".")
|
||||||
:marked
|
:marked
|
||||||
The `response` object does not hold our data in a form we can use directly.
|
The `response` object does not hold our data in a form we can use directly.
|
||||||
|
@ -274,7 +283,7 @@ block parse-json
|
||||||
|
|
||||||
.l-sub-section
|
.l-sub-section
|
||||||
:marked
|
:marked
|
||||||
We shouldn't expect the decoded JSON to be the heroes #{_array} directly.
|
We shouldn't expect the decoded JSON to be the heroes !{_array} directly.
|
||||||
The server we're calling always wraps JSON results in an object with a `data`
|
The server we're calling always wraps JSON results in an object with a `data`
|
||||||
property. We have to unwrap it to get the heroes.
|
property. We have to unwrap it to get the heroes.
|
||||||
This is conventional web api behavior, driven by
|
This is conventional web api behavior, driven by
|
||||||
|
@ -296,7 +305,7 @@ block parse-json
|
||||||
.callout.is-important
|
.callout.is-important
|
||||||
header HTTP GET is delayed
|
header HTTP GET is delayed
|
||||||
:marked
|
:marked
|
||||||
The `#{_priv}http.get` does **not send the request just yet!** This observable is
|
The `!{_priv}http.get` does **not send the request just yet!** This observable is
|
||||||
[*cold*](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/creating.md#cold-vs-hot-observables)
|
[*cold*](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/creating.md#cold-vs-hot-observables)
|
||||||
which means the request won't go out until something *subscribes* to the observable.
|
which means the request won't go out until something *subscribes* to the observable.
|
||||||
That *something* is the [HeroListComponent](#subscribe).
|
That *something* is the [HeroListComponent](#subscribe).
|
||||||
|
@ -328,7 +337,7 @@ a#hero-list-component
|
||||||
h4 #[b HeroListComponent] error handling
|
h4 #[b HeroListComponent] error handling
|
||||||
block hlc-error-handling
|
block hlc-error-handling
|
||||||
:marked
|
:marked
|
||||||
Back in the `HeroListComponent`, where we called `#{_priv}heroService.getHeroes()`,
|
Back in the `HeroListComponent`, where we called `!{_priv}heroService.getHeroes()`,
|
||||||
we supply the `subscribe` function with a second function parameter to handle the error message.
|
we supply the `subscribe` function with a second function parameter to handle the error message.
|
||||||
It sets an `errorMessage` variable which we've bound conditionally in the `HeroListComponent` template.
|
It sets an `errorMessage` variable which we've bound conditionally in the `HeroListComponent` template.
|
||||||
|
|
||||||
|
@ -401,7 +410,7 @@ code-example(format="." language="javascript").
|
||||||
### JSON results
|
### JSON results
|
||||||
|
|
||||||
As with `getHeroes()`, we [extract the data](#extract-data) from the response using the
|
As with `getHeroes()`, we [extract the data](#extract-data) from the response using the
|
||||||
`#{_priv}extractData()` helper.
|
`!{_priv}extractData()` helper.
|
||||||
|
|
||||||
block hero-list-comp-add-hero
|
block hero-list-comp-add-hero
|
||||||
:marked
|
:marked
|
||||||
|
@ -409,7 +418,7 @@ block hero-list-comp-add-hero
|
||||||
When the data, arrive it pushes the new hero object into its `heroes` array for presentation to the user.
|
When the data, arrive it pushes the new hero object into its `heroes` array for presentation to the user.
|
||||||
+makeExample('server-communication/ts/app/toh/hero-list.component.ts', 'addHero', 'app/toh/hero-list.component.ts (addHero)')(format=".")
|
+makeExample('server-communication/ts/app/toh/hero-list.component.ts', 'addHero', 'app/toh/hero-list.component.ts (addHero)')(format=".")
|
||||||
|
|
||||||
block promises
|
+ifDocsFor('ts')
|
||||||
h2#promises Fall back to Promises
|
h2#promises Fall back to Promises
|
||||||
:marked
|
:marked
|
||||||
Although the Angular `http` client API returns an `Observable<Response>` we can turn it into a
|
Although the Angular `http` client API returns an `Observable<Response>` we can turn it into a
|
||||||
|
@ -490,7 +499,7 @@ figure.image-display
|
||||||
block wikipedia-jsonp+
|
block wikipedia-jsonp+
|
||||||
:marked
|
:marked
|
||||||
Wikipedia offers a modern `CORS` API and a legacy `JSONP` search API. Let's use the latter for this example.
|
Wikipedia offers a modern `CORS` API and a legacy `JSONP` search API. Let's use the latter for this example.
|
||||||
The Angular `Jsonp` service both extends the `#{_Http}` service for JSONP and restricts us to `GET` requests.
|
The Angular `Jsonp` service both extends the `!{_Http}` service for JSONP and restricts us to `GET` requests.
|
||||||
All other HTTP methods throw an error because JSONP is a read-only facility.
|
All other HTTP methods throw an error because JSONP is a read-only facility.
|
||||||
|
|
||||||
As always, we wrap our interaction with an Angular data access client service inside a dedicated service, here called `WikipediaService`.
|
As always, we wrap our interaction with an Angular data access client service inside a dedicated service, here called `WikipediaService`.
|
||||||
|
@ -665,9 +674,9 @@ a#in-mem-web-api
|
||||||
registered for module loading by SystemJS (see `systemjs.config.js`)
|
registered for module loading by SystemJS (see `systemjs.config.js`)
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
The in-memory web API gets its data from #{_a_ca_class_with} a `createDb()`
|
The in-memory web API gets its data from !{_a_ca_class_with} a `createDb()`
|
||||||
method that returns a map whose keys are collection names and whose values
|
method that returns a map whose keys are collection names and whose values
|
||||||
are #{_array}s of objects in those collections.
|
are !{_array}s of objects in those collections.
|
||||||
|
|
||||||
Here's the class we created for this sample based on the JSON data:
|
Here's the class we created for this sample based on the JSON data:
|
||||||
+makeExample('server-communication/ts/app/hero-data.ts', null, 'app/hero-data.ts')(format=".")
|
+makeExample('server-communication/ts/app/hero-data.ts', null, 'app/hero-data.ts')(format=".")
|
||||||
|
@ -684,8 +693,10 @@ block redirect-to-web-api
|
||||||
To enable our server simulation, we replace the default `XHRBackend` service with
|
To enable our server simulation, we replace the default `XHRBackend` service with
|
||||||
the in-memory web API service using standard Angular provider registration techniques.
|
the in-memory web API service using standard Angular provider registration techniques.
|
||||||
We initialize the in-memory web API with *seed data* from the mock hero dataset at the same time.
|
We initialize the in-memory web API with *seed data* from the mock hero dataset at the same time.
|
||||||
|
:marked
|
||||||
|
Here is the revised (and final) version of <span ngio-ex>app/main.ts></span> demonstrating these steps.
|
||||||
|
|
||||||
p Here is the revised (and final) version of the #[code #[+adjExPath('app/main.ts')]] demonstrating these steps.
|
+makeExcerpt('app/main.ts', 'final')
|
||||||
+makeExample('server-communication/ts/app/main.ts', 'final', 'app/main.ts (final)')(format=".")
|
|
||||||
|
|
||||||
p See the full source code in the #[+liveExampleLink2()].
|
:marked
|
||||||
|
See the full source code in the <live-example></live-example>.
|
||||||
|
|
|
@ -15,7 +15,7 @@ block includes
|
||||||
- [understand the asterisk (\*) in **ngFor*](#asterisk)
|
- [understand the asterisk (\*) in **ngFor*](#asterisk)
|
||||||
- [write our own structural directive](#unless)
|
- [write our own structural directive](#unless)
|
||||||
|
|
||||||
p Try the #[+liveExampleLink2()].
|
Try the <live-example></live-example>.
|
||||||
|
|
||||||
<a id="definition"></a>
|
<a id="definition"></a>
|
||||||
.l-main-section
|
.l-main-section
|
||||||
|
|
|
@ -35,8 +35,7 @@ block includes
|
||||||
* [pipe](#pipe)
|
* [pipe](#pipe)
|
||||||
* [safe navigation operator (?.)](#safe-navigation-operator)
|
* [safe navigation operator (?.)](#safe-navigation-operator)
|
||||||
|
|
||||||
p.
|
The <live-example></live-example>
|
||||||
The #[+liveExampleLink2()]
|
|
||||||
demonstrates all of the syntax and code snippets described in this chapter.
|
demonstrates all of the syntax and code snippets described in this chapter.
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
|
|
|
@ -18,23 +18,26 @@ block includes
|
||||||
in #{_docsFor == 'ts' ? 'Dart' : 'TypeScript'} and JavaScript.
|
in #{_docsFor == 'ts' ? 'Dart' : 'TypeScript'} and JavaScript.
|
||||||
Just select either of those languages from the combo-box in the banner.
|
Just select either of those languages from the combo-box in the banner.
|
||||||
|
|
||||||
h1 Try it!
|
:marked
|
||||||
p
|
# Try it!
|
||||||
| Try the #[+liveExampleLink2()] which loads the sample app
|
|
||||||
+ifDocsFor('ts')
|
Try the <live-example></live-example> which loads the sample app
|
||||||
| in #[a(href="http://plnkr.co/" title="Plunker" target="_blank") plunker]
|
<span if-docs="ts">
|
||||||
| and displays the simple message:
|
in <a href="http://plnkr.co/" title="Plunker" target="_blank">plunker</a>
|
||||||
|
</span>
|
||||||
|
and displays the simple message:
|
||||||
|
|
||||||
figure.image-display
|
figure.image-display
|
||||||
img(src='/resources/images/devguide/quickstart/my-first-app.png' alt="Output of QuickStart app")
|
img(src='/resources/images/devguide/quickstart/my-first-app.png' alt="Output of QuickStart app")
|
||||||
|
|
||||||
h1 Build this app!
|
|
||||||
:marked
|
:marked
|
||||||
|
# Build this app!
|
||||||
|
|
||||||
- [Prerequisite](#prereq): Install #{_prereq}
|
- [Prerequisite](#prereq): Install #{_prereq}
|
||||||
- [Step 1](#create-and-configure): Create the app’s project folder and
|
- [Step 1](#create-and-configure): Create the app’s project folder and
|
||||||
define package dependencies and special project setup
|
define package dependencies and special project setup
|
||||||
- [Step 2](#root-component): Create the app’s Angular root component
|
- [Step 2](#root-component): Create the app’s Angular root component
|
||||||
- [Step 3](#main): Add `main.#{_docsFor}`, identifying the root component to Angular
|
- [Step 3](#main): Add <span ngio-ex>main.ts</span>, identifying the root component to Angular
|
||||||
- [Step 4](#index): Add `index.html`, the web page that hosts the application
|
- [Step 4](#index): Add `index.html`, the web page that hosts the application
|
||||||
- [Step 5](#build-and-run): Build and run the app
|
- [Step 5](#build-and-run): Build and run the app
|
||||||
- [Make some changes to the app](#make-some-changes)
|
- [Make some changes to the app](#make-some-changes)
|
||||||
|
@ -333,9 +336,9 @@ block create-main
|
||||||
[SEO](http://www.google.com/webmasters/docs/search-engine-optimization-starter-guide.pdf).
|
[SEO](http://www.google.com/webmasters/docs/search-engine-optimization-starter-guide.pdf).
|
||||||
These targets require a different kind of bootstrap function that we'd import from a different library.
|
These targets require a different kind of bootstrap function that we'd import from a different library.
|
||||||
|
|
||||||
### Why create separate *main.#{_docsFor}* and app component files?
|
### Why create separate *<span ngio-ex>main.ts</span>* and app component files?
|
||||||
|
|
||||||
Both `main.#{_docsFor}` and the app component files are tiny.
|
Both <span ngio-ex>main.ts</span> and the app component files are tiny.
|
||||||
This is just a QuickStart.
|
This is just a QuickStart.
|
||||||
We could have merged these two files into one
|
We could have merged these two files into one
|
||||||
and spared ourselves some complexity.
|
and spared ourselves some complexity.
|
||||||
|
@ -462,7 +465,7 @@ h2#index Step 4: Add #[code index.html]
|
||||||
|
|
||||||
a(id="my-app")
|
a(id="my-app")
|
||||||
:marked
|
:marked
|
||||||
When Angular calls the `bootstrap` function in `main.#{_docsFor}`, it reads the `AppComponent`
|
When Angular calls the `bootstrap` function in <span ngio-ex>main.ts</span>, it reads the `AppComponent`
|
||||||
metadata, finds the `my-app` selector, locates an element tag named `my-app`,
|
metadata, finds the `my-app` selector, locates an element tag named `my-app`,
|
||||||
and renders our application's view between those tags.
|
and renders our application's view between those tags.
|
||||||
|
|
||||||
|
|
|
@ -24,10 +24,9 @@ include ../_util-fns
|
||||||
Angular can do whatever we need it to do.
|
Angular can do whatever we need it to do.
|
||||||
We'll be covering a lot of ground at an introductory level but we’ll find plenty of links
|
We'll be covering a lot of ground at an introductory level but we’ll find plenty of links
|
||||||
to chapters with greater depth.
|
to chapters with greater depth.
|
||||||
|
|
||||||
|
Run the <live-example name="toh-6"></live-example>.
|
||||||
// #enddocregion intro
|
// #enddocregion intro
|
||||||
|
|
||||||
p Run the #[+liveExampleLink2('', 'toh-6')].
|
|
||||||
|
|
||||||
// #docregion main
|
// #docregion main
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
|
|
|
@ -5,8 +5,8 @@ include ../_util-fns
|
||||||
|
|
||||||
Every story starts somewhere. Our story starts where the [QuickStart](../quickstart.html) ends.
|
Every story starts somewhere. Our story starts where the [QuickStart](../quickstart.html) ends.
|
||||||
|
|
||||||
p Run the #[+liveExampleLink2('', 'toh-1')] for this part.
|
Run the <live-example></live-example> for this part.
|
||||||
:marked
|
|
||||||
Create a folder called `angular2-tour-of-heroes` and follow the [QuickStart](../quickstart.html) steps
|
Create a folder called `angular2-tour-of-heroes` and follow the [QuickStart](../quickstart.html) steps
|
||||||
which provide the prerequisites, the folder structure, and the core files for our Tour of Heroes.
|
which provide the prerequisites, the folder structure, and the core files for our Tour of Heroes.
|
||||||
|
|
||||||
|
@ -170,8 +170,8 @@ code-example(language="html").
|
||||||
using the built-in `ngModel` directive.
|
using the built-in `ngModel` directive.
|
||||||
* The `ngModel` directive also propagates changes to every other binding of the `hero.name`.
|
* The `ngModel` directive also propagates changes to every other binding of the `hero.name`.
|
||||||
|
|
||||||
p Run the #[+liveExampleLink2('', 'toh-1')] for this part.
|
Run the <live-example></live-example> for this part.
|
||||||
:marked
|
|
||||||
Here's the complete `app.component.ts` as it stands now:
|
Here's the complete `app.component.ts` as it stands now:
|
||||||
|
|
||||||
+makeExample('toh-1/ts/app/app.component.ts', 'pt1', 'app.component.ts')
|
+makeExample('toh-1/ts/app/app.component.ts', 'pt1', 'app.component.ts')
|
||||||
|
|
|
@ -6,8 +6,8 @@ include ../_util-fns
|
||||||
We’ll expand our Tour of Heroes app to display a list of heroes,
|
We’ll expand our Tour of Heroes app to display a list of heroes,
|
||||||
allow the user to select a hero, and display the hero’s details.
|
allow the user to select a hero, and display the hero’s details.
|
||||||
|
|
||||||
p Run the #[+liveExampleLink2('', 'toh-2')] for this part.
|
Run the <live-example></live-example> for this part.
|
||||||
:marked
|
|
||||||
Let’s take stock of what we’ll need to display a list of heroes.
|
Let’s take stock of what we’ll need to display a list of heroes.
|
||||||
First, we need a list of heroes. We want to display those heroes in the view’s template,
|
First, we need a list of heroes. We want to display those heroes in the view’s template,
|
||||||
so we’ll need a way to do that.
|
so we’ll need a way to do that.
|
||||||
|
@ -300,8 +300,8 @@ code-example(language="bash").
|
||||||
* We added the ability to select a hero and show the hero’s details
|
* We added the ability to select a hero and show the hero’s details
|
||||||
* We learned how to use the built-in directives `ngIf` and `ngFor` in a component’s template
|
* We learned how to use the built-in directives `ngIf` and `ngFor` in a component’s template
|
||||||
|
|
||||||
p Run the #[+liveExampleLink2('', 'toh-2')] for this part.
|
Run the <live-example></live-example> for this part.
|
||||||
:marked
|
|
||||||
### The Road Ahead
|
### The Road Ahead
|
||||||
Our Tour of Heroes has grown, but it’s far from complete.
|
Our Tour of Heroes has grown, but it’s far from complete.
|
||||||
We can't put the entire app into a single component.
|
We can't put the entire app into a single component.
|
||||||
|
|
|
@ -4,7 +4,7 @@ include ../_util-fns
|
||||||
Our app is growing.
|
Our app is growing.
|
||||||
Use cases are flowing in for reusing components, passing data to components, and creating more reusable assets. Let's separate the heroes list from the hero details and make the details component reusable.
|
Use cases are flowing in for reusing components, passing data to components, and creating more reusable assets. Let's separate the heroes list from the hero details and make the details component reusable.
|
||||||
|
|
||||||
p Run the #[+liveExampleLink2('', 'toh-3')] for this part.
|
Run the <live-example></live-example> for this part.
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
|
@ -243,7 +243,7 @@ code-example(format=".")
|
||||||
* We learned to bind a parent component to a child component.
|
* We learned to bind a parent component to a child component.
|
||||||
* We learned to declare the application directives we need in a `directives` array.
|
* We learned to declare the application directives we need in a `directives` array.
|
||||||
|
|
||||||
p Run the #[+liveExampleLink2('', 'toh-3')] for this part.
|
Run the <live-example></live-example> for this part.
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
|
|
|
@ -15,7 +15,7 @@ include ../_util-fns
|
||||||
Because data services are invariably asynchronous,
|
Because data services are invariably asynchronous,
|
||||||
we'll finish the chapter with a **!{_Promise}**-based version of the data service.
|
we'll finish the chapter with a **!{_Promise}**-based version of the data service.
|
||||||
|
|
||||||
p Run the #[+liveExampleLink2('', 'toh-4')] for this part.
|
Run the <live-example></live-example> for this part.
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
|
@ -343,8 +343,8 @@ a#child-component
|
||||||
* We created mock hero data and imported them into our service.
|
* We created mock hero data and imported them into our service.
|
||||||
* We designed our service to return a !{_Promise} and our component to get our data from the !{_Promise}.
|
* We designed our service to return a !{_Promise} and our component to get our data from the !{_Promise}.
|
||||||
|
|
||||||
p Run the #[+liveExampleLink2('', 'toh-4')] for this part.
|
Run the <live-example></live-example> for this part.
|
||||||
:marked
|
|
||||||
### The Road Ahead
|
### The Road Ahead
|
||||||
Our Tour of Heroes has become more reusable using shared components and services.
|
Our Tour of Heroes has become more reusable using shared components and services.
|
||||||
We want to create a dashboard, add menu links that route between the views, and format data in a template.
|
We want to create a dashboard, add menu links that route between the views, and format data in a template.
|
||||||
|
|
|
@ -18,7 +18,8 @@ figure.image-display
|
||||||
The [Routing and Navigation](../guide/router.html) chapter covers the router in more detail
|
The [Routing and Navigation](../guide/router.html) chapter covers the router in more detail
|
||||||
than we will in this tutorial.
|
than we will in this tutorial.
|
||||||
|
|
||||||
p Run the #[+liveExampleLink2('', 'toh-5')] for this part.
|
:marked
|
||||||
|
Run the <live-example></live-example> for this part.
|
||||||
|
|
||||||
.l-sub-section
|
.l-sub-section
|
||||||
img(src='/resources/images/devguide/plunker-separate-window-button.png' alt="pop out the window" align="right" style="margin-right:-20px")
|
img(src='/resources/images/devguide/plunker-separate-window-button.png' alt="pop out the window" align="right" style="margin-right:-20px")
|
||||||
|
@ -662,11 +663,10 @@ figure.image-display
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
## Application structure and code
|
## Application structure and code
|
||||||
p.
|
|
||||||
Review the sample source code in the #[+liveExampleLink2('', 'toh-5')] for this chapter.
|
Review the sample source code in the <live-example></live-example> for this chapter.
|
||||||
Verify that we have the following structure:
|
Verify that we have the following structure:
|
||||||
|
|
||||||
:marked
|
|
||||||
.filetree
|
.filetree
|
||||||
.file angular2-tour-of-heroes
|
.file angular2-tour-of-heroes
|
||||||
.children
|
.children
|
||||||
|
|
|
@ -17,7 +17,7 @@ block includes
|
||||||
|
|
||||||
In this chapter we teach our application to make the corresponding HTTP calls to a remote server's web API.
|
In this chapter we teach our application to make the corresponding HTTP calls to a remote server's web API.
|
||||||
|
|
||||||
p Run the #[+liveExampleLink2('', 'toh-6')] for this part.
|
Run the <live-example></live-example> for this part.
|
||||||
|
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
|
@ -57,7 +57,7 @@ block http-providers
|
||||||
|
|
||||||
:marked
|
:marked
|
||||||
We should be able to access `!{_Http}` services from anywhere in the application.
|
We should be able to access `!{_Http}` services from anywhere in the application.
|
||||||
So we register them in the `bootstrap` call of `main.!{_docsFor}` where we
|
So we register them in the `bootstrap` call of <span ngio-ex>main.ts</span> where we
|
||||||
launch the application and its root `AppComponent`.
|
launch the application and its root `AppComponent`.
|
||||||
|
|
||||||
+makeExcerpt('app/main.ts','v1')
|
+makeExcerpt('app/main.ts','v1')
|
||||||
|
@ -361,8 +361,8 @@ block review
|
||||||
.l-main-section
|
.l-main-section
|
||||||
:marked
|
:marked
|
||||||
## Application structure and code
|
## Application structure and code
|
||||||
p.
|
|
||||||
Review the sample source code in the #[+liveExampleLink2('', 'toh-6')] for this chapter.
|
Review the sample source code in the <live-example></live-example> for this chapter.
|
||||||
Verify that we have the following structure:
|
Verify that we have the following structure:
|
||||||
|
|
||||||
block filetree
|
block filetree
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Angular.io Example Conditional Directive
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* <tag if-docs="ts|dart">...</tag>
|
||||||
|
*
|
||||||
|
* This is equivalent to an ngIf that holds if this containing
|
||||||
|
* docs are for TypeScript.
|
||||||
|
*/
|
||||||
|
|
||||||
|
angularIO.directive('ifDocs', ['ngIfDirective', '$location', function (ngIfDirective, $location) {
|
||||||
|
var ngIf = ngIfDirective[0];
|
||||||
|
|
||||||
|
return {
|
||||||
|
transclude: ngIf.transclude,
|
||||||
|
priority: ngIf.priority,
|
||||||
|
terminal: ngIf.terminal,
|
||||||
|
restrict: ngIf.restrict,
|
||||||
|
link: function (scope, element, attrs) {
|
||||||
|
var ngIfCond = (attrs.ifDocs === 'dart') == !NgIoUtil.isDartDoc($location);
|
||||||
|
attrs.ngIf = function () { return !ngIfCond; }
|
||||||
|
ngIf.link.apply(ngIf, arguments);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}]);
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Angular.io Live Example Directive
|
||||||
|
*
|
||||||
|
* Renders a link to a live/host example of the doc chapter
|
||||||
|
* app this directive is contained in.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* <live-example [name="..."] [noSource] [srcText="..."]>text</live-example>
|
||||||
|
* Example:
|
||||||
|
* <p>Run <live-example name="toh-1">this chapter's example</live-example></p>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
angularIO.directive('liveExample', ['$location', function ($location) {
|
||||||
|
|
||||||
|
function a(text, attrs) {
|
||||||
|
var attr = (attrs.href ? ' href="' + attrs.href + '"' : '') +
|
||||||
|
(attrs.target ? ' target="' + attrs.target + '"' : '');
|
||||||
|
return '<a' + attr + '>' + text + '</a>';
|
||||||
|
}
|
||||||
|
|
||||||
|
function span(text) { return '<span>' + text + '</span>'; }
|
||||||
|
|
||||||
|
return {
|
||||||
|
restrict: 'E',
|
||||||
|
|
||||||
|
compile: function (tElement, attrs) {
|
||||||
|
var text = tElement.text() || 'live example';
|
||||||
|
var ex = attrs.name || NgIoUtil.getExampleName($location);
|
||||||
|
var href, template;
|
||||||
|
|
||||||
|
var isForDart = attrs.lang === 'dart' || NgIoUtil.isDartDoc($location);
|
||||||
|
var href = isForDart
|
||||||
|
? 'http://angular-examples.github.io/' + ex
|
||||||
|
: '/resources/live-examples/' + ex + '/ts/plnkr.html';
|
||||||
|
|
||||||
|
// Link to live example.
|
||||||
|
var template = a(text, { href: href, target: '_blank' });
|
||||||
|
|
||||||
|
// The hosted example and sources are in different locations for Dart.
|
||||||
|
// Also show link to sources for Dart, unless noSource is specified.
|
||||||
|
if (isForDart && !attrs.hasOwnProperty('nosource')) {
|
||||||
|
var srcText = attrs.srcText || 'view source';
|
||||||
|
var srcHref = 'http://github.com/angular-examples/' + ex;
|
||||||
|
template = span(template + ' (' + a(srcText, { href: srcHref, target: '_blank' }) + ')');
|
||||||
|
}
|
||||||
|
|
||||||
|
// UPDATE ELEMENT WITH NEW TEMPLATE
|
||||||
|
tElement.html(template);
|
||||||
|
|
||||||
|
// RETURN ELEMENT
|
||||||
|
return function (scope, element, attrs) { };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}]);
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Angular.io Example File Path Directive
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* <span ngio-ex [lang="ts|dart"]>some_path</span>
|
||||||
|
* <ngio-ex path="some_path" [lang="ts|dart"]></ngio-ex>
|
||||||
|
*
|
||||||
|
* The latter gets treated as a block tag in markdown when at the start of a line.
|
||||||
|
*
|
||||||
|
* Yields
|
||||||
|
* <code>some_path_possibly_adjusted</code>
|
||||||
|
*
|
||||||
|
* The given path is assumed to be a TS app directory or
|
||||||
|
* source file path. When this directive is used in Dart docs
|
||||||
|
* it adjusts the path to conform to Dart directory and file
|
||||||
|
* name conventions. See NgIoUtil.adjustTsExamplePathForDart()
|
||||||
|
* for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
angularIO.directive('ngioEx', ['$location', function ($location) {
|
||||||
|
return {
|
||||||
|
restrict: 'AE',
|
||||||
|
|
||||||
|
compile: function (tElement, attrs) {
|
||||||
|
var examplePath = attrs.path || tElement.text();
|
||||||
|
if (NgIoUtil.isDartDoc($location) || attrs.lang === 'dart') {
|
||||||
|
examplePath = NgIoUtil.adjustTsExamplePathForDart(examplePath);
|
||||||
|
}
|
||||||
|
var template = '<code>' + examplePath + '</code>';
|
||||||
|
|
||||||
|
// UPDATE ELEMENT WITH NEW TEMPLATE
|
||||||
|
tElement.html(template);
|
||||||
|
|
||||||
|
// RETURN ELEMENT
|
||||||
|
return function (scope, element, attrs) { };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}]);
|
|
@ -0,0 +1,87 @@
|
||||||
|
// This will be nicer once we switch to Ng2. For now, define a singleton.
|
||||||
|
|
||||||
|
var NgIoUtil = (function () {
|
||||||
|
|
||||||
|
function NgIoUtil() { }
|
||||||
|
|
||||||
|
NgIoUtil.isDartDoc = function ($location) {
|
||||||
|
var loc = $location.absUrl();
|
||||||
|
return loc.includes('/docs/dart/');
|
||||||
|
};
|
||||||
|
|
||||||
|
// The following util functions are adapted from _utils-fn.jade.
|
||||||
|
// Note that basename(), etc doesn't quite follow
|
||||||
|
// https://nodejs.org/api/path.html
|
||||||
|
// but it suits our purpose for now.
|
||||||
|
|
||||||
|
NgIoUtil.adjustTsExamplePathForDart = function (_path) {
|
||||||
|
/* Convert a TS example path into a Dart example path. E.g.,
|
||||||
|
*
|
||||||
|
* - app/main.ts -> web/main.dart
|
||||||
|
* - displaying-data/ts/app/app.component.2.ts -> displaying-data/dart/lib/app_component.dart
|
||||||
|
*
|
||||||
|
* Notice that the '.2' is dropped from the name.
|
||||||
|
*/
|
||||||
|
if (!_path) return _path;
|
||||||
|
var path = _path.trim();
|
||||||
|
var folder = NgIoUtil.folderName(path);
|
||||||
|
var ext = NgIoUtil.extname(path);
|
||||||
|
var baseNameNoExt = NgIoUtil.basename(path, ext);
|
||||||
|
var inWebFolder = baseNameNoExt.match(/^(main|index)(\.\d)?$/);
|
||||||
|
|
||||||
|
// Adjust the folder path, e.g., '/ts/' -> '/dart/'
|
||||||
|
folder = folder
|
||||||
|
.replace(/(^|\/)ts($|\/)/, '$1dart$2')
|
||||||
|
.replace(/(^|\/)app($|\/)/, inWebFolder ? '$1web$2' : '$1lib$2');
|
||||||
|
|
||||||
|
// Special case not handled above: e.g., index.html -> web/index.html
|
||||||
|
if (baseNameNoExt.match(/^(index|styles)(\.\d)?$/) && !folder.match(/web$/))
|
||||||
|
folder = (folder ? folder + '/' : '') + 'web';
|
||||||
|
|
||||||
|
// In file name, replace special characters with underscore
|
||||||
|
baseNameNoExt = baseNameNoExt.replace(/[\-\.]/g, '_');
|
||||||
|
|
||||||
|
// Adjust the file extension
|
||||||
|
if (ext == '.ts') ext = '.dart';
|
||||||
|
return (folder ? folder + '/' : '') + baseNameNoExt + ext;
|
||||||
|
};
|
||||||
|
|
||||||
|
NgIoUtil.extname = function (path) {
|
||||||
|
var i = path.lastIndexOf('.');
|
||||||
|
return i > 0 ? path.substr(i) : '';
|
||||||
|
};
|
||||||
|
|
||||||
|
NgIoUtil.basename = function (path, optExt) {
|
||||||
|
var i = path.lastIndexOf('/');
|
||||||
|
var name = i > 0 ? path.substr(i + 1) : path;
|
||||||
|
if (optExt) name = name.substr(0, name.length - optExt.length);
|
||||||
|
return name;
|
||||||
|
};
|
||||||
|
|
||||||
|
NgIoUtil.folderName = function (path) {
|
||||||
|
var i = path.lastIndexOf('/');
|
||||||
|
return i > 0 ? path.substr(0, i) : '';
|
||||||
|
};
|
||||||
|
|
||||||
|
NgIoUtil._exampleName = ''; // example name is unique to a page; e.g., toh-1
|
||||||
|
|
||||||
|
NgIoUtil.setExampleName = function (name) {
|
||||||
|
// Adjust name for known cases where chapter name is not the example name.
|
||||||
|
var matches = name.match(/(toh-)pt(\d+)/);
|
||||||
|
if (matches) name = matches[1] + matches[2];
|
||||||
|
NgIoUtil._exampleName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
NgIoUtil.getExampleName = function ($location) {
|
||||||
|
if (!NgIoUtil._exampleName) {
|
||||||
|
// TODO: use $location.path() instead(?). It seems to be empty.
|
||||||
|
var loc = $location.absUrl();
|
||||||
|
// E.g., https://example.com/docs/dart/latest/guide/displaying-data.html
|
||||||
|
var matches = loc.match(/.*\/([\w\.\-]+)\.html/);
|
||||||
|
if (matches) NgIoUtil.setExampleName(matches[1]); // cache name
|
||||||
|
}
|
||||||
|
return NgIoUtil._exampleName;
|
||||||
|
};
|
||||||
|
|
||||||
|
return NgIoUtil;
|
||||||
|
} ());
|
Loading…
Reference in New Issue