` elements as we’re going to custom style them.
++makeExample('toh-4/ts-snippets/app/index.pt4.html','ng-for')
+:marked
+ We’ve been down this road before. We are using the `ngFor` directive, so we have to declare it in the component. Let’s do that now by first importing `CORE_DIRECTIVES`. (Remember that `CORE_DIRECTIVES` is a convenience array containing the most common directives such as `ngFor`.)
+ ```
+ import {Component, CORE_DIRECTIVES} from 'angular2/angular2';
+ ```
+ Then we declare the `CORE_DIRECTIVES` to the component.
+ ```
+ directives: [CORE_DIRECTIVES]
+ ```
+ ### Using the Shared HeroService
+ We just iterated over a list of heroes, but we don’t have any heroes in the `DashboardComponent`. We do have a `HeroService` that provides heroes. In fact, we already used this service in the `HeroComponent`. Let’s re-use this same service for the `DashboardComponent` to get a list of heroes.
+
+ We’ll create a `heroes` property in our `DashboardComponent`.
+ ```
+ public heroes: Hero[];
+ ```
+ And we import the `Hero`
+ ```
+ import {Hero} from './hero';
+ ```
+ #### Injecting a Service
+ We’ll be needing the `HeroService`, so let’s import it and inject it into our `DashboardComponent`. Here we import it.
+ ```
+ import {HeroService} from './hero.service';
+ ```
+ And here we inject it into our component’s constructor.
+ ```
+ constructor(private _heroService: HeroService) { }
+ ```
+ #### Getting the Heroes on Initialization
+ We want our heroes to be loaded when the component is initialized, just like we did in the `HeroesComponent`. We’ll tackle this the same way, by using the onInit Lifecycle hook.
+
+ We can implement the `OnInit` interface and code the `onInit` method.
+ ```
+ export class DashboardComponent implements OnInit {
+ ```
+ Here we implement the `onInit` method to get our heroes, again just like we did for the `HeroesComponent`.
++makeExample('toh-4/ts-snippets/app/app.component.pt4.ts','oninit')
+:marked
+ Notice we did not have to know how to get the heroes, we just needed to know the method to call from the `HeroService`. This is an advantage of using shared services.
+
+ When we view our app in the browser we see the dashboard light up with all of our heroes. This isn’t exactly what we want so let’s trim that down to the top four heroes.
+
+ ### Slicing with Pipes
+ Our requirement is to show the top four heroes. If only we had something that would automatically get a subset of the data. Well, we do! They are called Pipes.
+
+ Angular has various built-in pipes that make formatting and filtering data easy. We’ll take advantage of a pipe named `slice` to get a slice of our heroes array.
+ ```
+
+ ```
+ After the `ngFor` we added a pipe character and then the `slice` pipe. We tell the `slice` pipe to start at the 0th item in the array and get four items.
+.l-sub-section
+ :marked
+ Learn more about Pipes in the chapter [Pipes](../guide/pipes.html)
+:marked
+ When we view our app we now see the first four heroes are displayed.
+
+ ### Heroes with Style
+ Our creative designers have added a requirement that the dashboard should show the heroes in a row of rectangles. We’ve written some CSS to achieve this along with some simple media queries to achieve responsive design.
+
+ We could put the CSS in the component, but there are over 30 lines of CSS and it would get crowded fast. Most editors make it easier to code CSS in a *.css file too. Fortunately, we can separate the styles into their own file and reference them.
+
+ #### Adding the Dashboard’s CSS File
+ Let’s create a file to hold the `DashboardComponent`’s CSS. We’ll name it `dashboard.component.css` and put it in the `app` folder.
+
+ Now let’s add the following CSS to the file.
++makeExample('toh-4/ts-snippets/app/index.pt4.html','css')
+:marked
+ We need to reference the file from our component so the styles will be applied properly. Let’s add this reference to the component’s `styleUrls` property.
+ ```
+ styleUrls: ['app/dashboard.component.css'],
+ ```
+ The `styleUrls` property is an array, which we might guess suggests that we can add multiple styles from different locations. And we would be right! In this case we have one file, but we could add more for our component if needed.
+
+ #### Template Urls
+ While we are at it, let’s move our HTML for the `DashboardComponent` to its own file. We’ll create a file named `dashboard.component.html` in the `app` folder and move the HTML there.
+ We need to reference the the template, so let’s change our component’s `template` property to `templateUrl` and set it to the location of the file.
+ ```
+ template: 'app/dashboard.component.html',
+ ```
+ Notice we are now using single quotes and not the back-ticks since we only have the need for a single line string.
+
+ #### Applying the Styles to Our Template
+
+ Now that we have some style, let’s take advantage of it by applying it to our template. Our template should now look like this:
++makeExample('toh-4/ts-snippets/app/index.pt4.html','template-styled')
+:marked
+ When we view our app in the browser it now shows our dashboard with our four top heroes in a row.
+
+ ## Styling the Navigation Links
+ Our creative design team requested that the navigation links also be styled. Let’s make the navigation links look more like selectable buttons.
+
+ ### Defining Styles for Navigation Links
+ Let’s add the following styles to our `AppComponent`’s `styles` property. We’ll define some classes named `router-link` that style the default, active, visited and hover selectors. The active selector changes the color of the link to make it easy to identify which link is selected.
++makeExample('toh-4/ts-snippets/app/app.component.pt4.ts','styles')
+:marked
+ This time we define the styles in our component because there are only a few of them.
+
+ ### Applying Styles to the Navigation Links
+ Now that we have styles for our navigation links, let’s apply them in the `AppComponent` template. When we are done, our component will look like the following:
++makeExample('toh-4/ts-snippets/app/index.pt4.html','styled-nav-links')
+:marked
+ #### Where Did the Active Route Come From?
+ The Angular Router makes it easy for us to style our active navigation link. The `router-link-active` class is automatically added to the Router’s active route for us. So all we have to do is define the style for it.
+
+ Sweet! When we view our app in the browser we see the navigation links are now styled, as are our top heroes!
+figure.image-display
+ img(src='/resources/images/devguide/toh/dashboard-top-heroes.png' alt="View navigations")
+:marked
+ ## Add Route to Hero Details
+ We can navigate between the dashboard and the heroes view, but we have a requirement from our users to be able to select a hero from either of those views and go directly to the selected hero’s details. Let’s configure a route to go directly to the `HeroDetailComponent` passing the hero’s id as a parameter.
+
+ ### Configuring a Route with a Parameter
+ We’ve already added a few routes to the `routes.config.ts` file, so it’s natural that we’d start there to add the route to go to the `HeroDetailComponent`. Let’s start by adding the import statement for the component.
++makeExample('toh-4/ts-snippets/app/route.config.pt4.ts','route-parameter-import')
+:marked
+ Now we add a route for the details to the `Routes` object.
++makeExample('toh-4/ts-snippets/app/route.config.pt4.ts','route-parameter-detail')
+:marked
+ The route will lead to the `HeroDetailComponent`, passing along the value for the hero’s id. The routing configuration identifies parameters as parts of the path that are prefixed with a `:` such as `:id`.
+
+ ### Receiving a Parameter
+ We want to navigate to the `HeroDetailComponent`, so let’s modify it to accept the `id` parameter. We import the `RouteParams` so we can access the parameter.
+ We assign our `AppComponent` a selector of `my-app`.
++makeExample('toh-4/ts-snippets/app/app.component.pt4.ts','import-params')
+:marked
+ Now we inject the `RouteParams` into the `HeroDetailComponent` constructor.
++makeExample('toh-4/ts-snippets/app/app.component.pt4.ts','inject-routeparams')
+:marked
+ We want to immediately access the parameter, so let’s implement the `OnInit` interface and its `onInit` method.
++makeExample('toh-4/ts-snippets/app/app.component.pt4.ts','access-params')
+:marked
+ And let’s not forget to import `OnInit`.
++makeExample('toh-4/ts-snippets/app/app.component.pt4.ts','import-onit')
+:marked
+ Using the `onInit`method, we can grab the parameter as soon as the component initializes. We’ll access the parameter by name and later we’ll get the hero by its `id`.
++makeExample('toh-4/ts-snippets/app/app.component.pt4.ts','onit-id-param')
+:marked
+ Our `HeroDetailComponent` is already used in the `HeroesComponent`. When we select a hero from the list we are passing the hero object from the list to the `HeroDetailComponent`. We want this component to support that functionality or be able to accept the hero’s id. Let’s revise the logic in the `onInit` to handle this.
++makeExample('toh-4/ts-snippets/app/app.component.pt4.ts','onit-hero-id')
+:marked
+ Our component will first check if it has a hero. If it doesn’t it will then check for the routing parameter so it can get the hero.
+.l-sub-section
+ :marked
+ Learn more about RouteParams in the chapter [Router](../guide/router.html)
+:marked
+ Getting the Hero
+ When we pass the id to the `HeroDetailComponent` we need to go get the hero from our `HeroService`. Let’s import the `HeroService` so we can use it to get our hero.
++makeExample('toh-4/ts-snippets/app/bootstrap.pt4.ts','import-hero-service')
+:marked
+ And then we inject the `HeroService` into the constructor.
++makeExample('toh-4/ts-snippets/app/app.component.pt4.ts','inject-hero-service')
+:marked
+ We then stub out the call to the `HeroService` to get the hero by the hero’s id. But wait a second, we don’t have a way to get the hero by id … yet.
+
+ Our `HeroService` is the right place to get a single hero. We’ll create a method named `getHero` that will accept a parameter, find the hero, and return the hero in a promise.
+
+ We add this method to the `HeroService`.
++makeExample('toh-4/ts-snippets/app/hero.service.pt4.ts','get-hero-method')
+:marked
+ Then we go back to our `HeroDetailComponent` and we can call the `getHero` method.
++makeExample('toh-4/ts-snippets/app/app.component.pt4.ts','onit-hero-method')
+:marked
+ We grab the hero and set it to the local `hero` property. Now we have everything in place to receive the parameter.
+
+ ### Select a Hero on the Dashboard
+ When a user selects a hero in the dashboard, we want to route to the details. Let’s open our dashboard’s template and add a click event to each hero in the template.
++makeExample('toh-4/ts-snippets/app/index.pt4.html','select-hero-click-event')
+:marked
+ The click event will call the `gotoDetail` method in the `DashboardComponent`. We don’t have that method yet, so let’s create it. We’ll want to use the router to navigate to the details route we created. So we have to import the router, and while we are at it, we’ll import the `Routes` object we created that describe our routes.
++makeExample('toh-4/ts-snippets/app/bootstrap.pt4.ts','import-router')
+:marked
+ Now we can write our method to navigate to the route and pass the parameter. We’ll use the router’s `navigate` method and pass an array that has 2 parameters. The first is the name of the route (the `as` property in the `RouteConfig`). The second is an object with the parameters and values.
++makeExample('toh-4/ts-snippets/app/route.config.pt4.ts','router-navigate-method')
+:marked
+ Now when we view our app in the browser and select a hero from the dashboard, we go directly to the hero’s details!
+.l-sub-section
+ :marked
+ Learn more about RouteParams in the chapter [Router](../guide/router.html)
+:marked
+ ### Select a Hero on the HeroesComponent
+ When a user selects a hero in the dashboard, we go to the details. But we also want this to happen from the `HeroesComponent`. Let’s add the same changes to the `HeroesComponent` that we made to the dashboard.
++makeExample('toh-4/ts-snippets/app/app.component.pt4.ts','select-hero')
+:marked
+ The requirement here is to show the hero when selected and allow the user to the details via a button. So when a user selects a hero we want to show the hero’s name and provide a button to navigate to the details.
+
+ Let’s open the `HeroesComponent`, remove the `my-hero-detail` component, and change the template to display the hero’s name instead.
++makeExample('toh-4/ts-snippets/app/index.pt4.html','display-hero-name')
+:marked
+ We also added a button with a click event that will call our `gotoDetail` method in our `HeroesComponent`.
+
+ Notice we also used the `uppercase` pipe to format the selected hero’s name. Pipes are extremely helpful at formatting and filtering.
+.l-sub-section
+ :marked
+ Learn more about Pipes in the chapter [Pipes](../guide/pipes.html)
+:marked
+ When we view the app in our browser we can now navigate from the dashboard or the heroes component directly to the selected hero’s details!
+
+ ### Cleaning Up Templates and Styles
+ We’ve added a lot of HTML and CSS in our template and styles, respectively, in the `HeroesComponent`. Let’s move each of these to their own files.
+
+ We move the HTML for the `HeroesComponent` template to `heroes.component.html`. Then we reference the file in the component’s `templateUrl` property.
+
+ Now our `HeroesComponent` looks much cleaner and easier to maintain since our template and styles are in another file.
++makeExample('toh-4/ts-snippets/app/app.component.pt4.ts','reference-heroes-component')
+:marked
+ We’ll also move the HTML out of the `HeroDetailComponent` and into its own file named `hero-detail.component.html`. Then we reference the file from the `templateUrl` property.
++makeExample('toh-4/ts-snippets/app/app.component.pt4.ts','reference-hero-detail-component')
+:marked
+ ### Adding Styles to the App
+ When we add styles to a component we are making it easier to package everything a component needs together. The HTML, the CSS, and the code are all together in one convenient place. However we can also add styles at an app level outside of a component.
+
+ Our designers just gave us a few more basic styles to apply to our entire app. Let’s add some CSS in a file `styles.css` to the `src` folder to style the app’s basic elements.
++makeExample('toh-4/ts-snippets/app/index.pt4.html','basic-styles')
+:marked
+ And let’s reference the stylesheet from the `index.html`.
++makeExample('toh-4/ts-snippets/app/index.pt4.html','stylesheet')
+:marked
+ When we view our app in the browser we can see everything still works as expected!
+
+ ### Reviewing the App Structure
+ Let’s verify that we have the following structure after all of our good refactoring in this chapter:
+
+.filetree
+ .file angular2-tour-of-heroes
+ .children
+ .file node_modules
+ .file app
+ .children
+ .file app.component.ts
+ .file boot.ts
+ .file dashboard.component.css
+ .file dashboard.component.html
+ .file dashboard.component.ts
+ .file hero.ts
+ .file hero-detail.component.html
+ .file hero-detail.component.ts
+ .file hero.service.ts
+ .file heroes.component.css
+ .file heroes.component.html
+ .file heroes.component.ts
+ .file mock-heroes.ts
+ .file index.html
+ .file package.json
+ .file styles.css
+ .file tsconfig.json
+:marked
+
+.l-main-section
+:marked
+ ## Recap
+
+ ### The Road We’ve Travelled
+ Let’s take stock in what we’ve built.
+ - We added the router to navigate between different components and their templates
+ - We learned how to create router links to represent navigation menu items
+ - We extended a component to either accept a hero as input or accept a router parameter to get the hero
+ - We extended our shared service by adding a new method to it
+ - We added the `slice` pipe to filter the top heroes, and the `uppercase` pipe to format data
+
+ ### The Road Ahead
+ Our Tour of Heroes has grown to reuse services, share components, route between components and their templates, and filter and format data with pipes. We have many of the foundations to build an application. In the next chapter we’ll explore how to replace our mock data with real data using http.
\ No newline at end of file
diff --git a/public/docs/ts/latest/guide/hierarchical-dependency-injection.jade b/public/docs/ts/latest/guide/hierarchical-dependency-injection.jade
index 82133e09c9..b06183be6e 100644
--- a/public/docs/ts/latest/guide/hierarchical-dependency-injection.jade
+++ b/public/docs/ts/latest/guide/hierarchical-dependency-injection.jade
@@ -9,9 +9,9 @@ include ../../../../_includes/_util-fns
that parallel an application's component tree.
We can re-configure the injectors at any level of that component tree with
interesting and useful results.
-
+
In this chapter we explore these points and write some code.
-
+
[Live Example](/resources/live-examples/hierarchical-dependency-injection/ts/plnkr.html).
.l-main-section
@@ -21,19 +21,19 @@ include ../../../../_includes/_util-fns
In the [Dependency Injection](./dependency-injection.html) chapter
we learned how to configure a dependency injector and how to retrieve dependencies where we need them.
- We oversimplified. In fact, there is no such thing as ***the*** injector!
+ We oversimplified. In fact, there is no such thing as ***the*** injector!
An application may have multiple injectors!
An Angular application is a tree of components. Each component instance has its own injector!
The tree of components parallels the tree of injectors.
-
+
.l-sub-section
:marked
- Angular doesn't *literally* create a separate injector for each component.
- Every component doesn't need its own injector and it would be horribly inefficient to create
+ Angular doesn't *literally* create a separate injector for each component.
+ Every component doesn't need its own injector and it would be horribly inefficient to create
masses of injectors for no good purpose.
-
+
But it is true that every component ***has an injector*** (even if it shares that injector with another component)
and there may be many different injector instances operating at different levels of the component tree.
@@ -135,12 +135,12 @@ figure.image-display
Our `HeroEditComponent` uses this services under the hood for it’s `hero` property. It intercepts the `get` and `set` method to delegate the actual work to our `RestoreService` which in turn makes sure that we won’t work on the original item but on a copy instead.
- At this point we may be scratching our heads asking what this has to do with component injectors?
- If closely at the metadata for our `HeroEditComponent`. Notice the `providers` property.
+ At this point we may be scratching our heads asking what this has to do with component injectors?
+ Look closely at the metadata for our `HeroEditComponent`. Notice the `providers` property.
+makeExample('hierarchical-dependency-injection/ts/app/hero-editor.component.ts', 'providers')
:marked
- This adds a `RestoreService` provider to the injector of the `HeroEditComponent`.
+ This adds a `RestoreService` provider to the injector of the `HeroEditComponent`.
Couldn’t we simply alter our bootstrap call to this?
+makeExample('hierarchical-dependency-injection/ts/app/boot.ts', 'bad-alternative')
@@ -155,11 +155,11 @@ figure.image-display
Any of those injectors could have its own instance of the service.
If we defined a `RestoreService` provider only on the root component,
- we would have exactly one instance of that service and it would be shared across the entire application.
-
+ we would have exactly one instance of that service and it would be shared across the entire application.
+
That’s clearly not what we want in this scenario. We want each component to have its own instance of the `RestoreService`.
Defining (or re-defining) a provider at the component level creates a new instance of the service for each new instance
- of that component. We've made the `RestoreService` a kind of "private" singleton for each `HeroEditComponent`,
+ of that component. We've made the `RestoreService` a kind of "private" singleton for each `HeroEditComponent`,
scoped to that component instance and its child components.
@@ -21,11 +21,11 @@ include ../../../../_includes/_util-fns
## The Lifecycle Hooks
Directive and component instances have a lifecycle
as Angular creates, updates, and destroys them.
-
+
Developers can tap into key moments in that lifecycle by implementing
one or more of the "Lifecycle Hook" interfaces, all of them available
- in the `angular2/core` library.
-
+ in the `angular2/core` library.
+
Here is the complete lifecycle hook interface inventory:
* `OnInit`
@@ -39,10 +39,10 @@ include ../../../../_includes/_util-fns
No directive or component will implement all of them and some of them only make
sense for components.
-
+
Each interface has a single hook method whose name is the interface name prefixed with `ng`.
- For example, the `OnInit` interface has a hook method names `ngOnInit`.
-
+ For example, the `OnInit` interface has a hook method named `ngOnInit`.
+
Angular calls these hook methods in the following order:
* `ngOnChanges` - called when an input or output binding value changes
* `ngOnInit` - after the first `ngOnChanges`
@@ -52,7 +52,7 @@ include ../../../../_includes/_util-fns
* `ngAfterViewInit` - after component's view(s) are initialized
* `ngAfterViewChecked` - after every check of a component's view(s)
* `ngOnDestroy` - just before the directive is destroyed.
-
+
The [live example](/resources/live-examples/lifecycle-hooks/ts/plnkr.html) demonstrates
these hooks.
@@ -65,26 +65,26 @@ include ../../../../_includes/_util-fns
with its own change detection processing
we would also add a `ngDoCheck` method. We would **not** implement `ngOnChanges`.
We write either `ngOnChanges` or `ngDoCheck`, not both.
-
- Custom change detection and `ngDoCheck` are on our documentation backlog.
+
+ Custom change detection and `ngDoCheck` are on our documentation backlog.
:marked
Peek-a-boo is a demo. We'd rarely if ever implement all interfaces like this in real life.
We look forward to explaining the Peek-a-boo example and the other lifecycle hook examples in
- an update to this chapter. Meanwhile, please enjoy poking around in the
+ an update to this chapter. Meanwhile, please enjoy poking around in the
[code](/resources/live-examples/lifecycle-hooks/ts/plnkr.html).
-
+
## Interface optional?
The lifecycle interfaces are optional.
- We recommend adding them to benefit from TypeScript's strong typing and editor tooling.
-
- But they disappear from the transpiled JavaScript.
+ We recommend adding them to benefit from TypeScript's strong typing and editor tooling.
+
+ But they disappear from the transpiled JavaScript.
Angular can't see them at runtime. And they are useless to someone developing in
a language without interfaces (such as pure JavaScript).
-
- Fortunately, they aren't necessary.
+
+ Fortunately, they aren't necessary.
We don't have to add the lifecycle hook interfaces to our directives and components to benefit from the hooks themselves.
-
+
Angular instead inspects our directive and component classes
and calls the hook methods *if they are defined*.
- Angular will find and call methods like `ngOnInit()`, with or without the interfaces.
+ Angular will find and call methods like `ngOnInit()`, with or without the interfaces.
diff --git a/public/docs/ts/latest/guide/template-syntax.jade b/public/docs/ts/latest/guide/template-syntax.jade
index 4dc86d2275..b9162075e6 100644
--- a/public/docs/ts/latest/guide/template-syntax.jade
+++ b/public/docs/ts/latest/guide/template-syntax.jade
@@ -16,6 +16,8 @@ include ../../../../_includes/_util-fns
>[Template expressions](#template-expressions)
+ >[Template statements](#template-statements)
+
>[Binding syntax](#binding-syntax)
>[Property Binding](#property-binding)
@@ -82,67 +84,156 @@ include ../../../../_includes/_util-fns
But it is not literally true. Interpolation is actually a special syntax that Angular converts into a
[Property Binding](#property-binding) as we explain below. The implications and consequences can be profound.
- But before we explore that assertion, we’ll take a closer look at template expressions.
+ But before we explore that assertion, we’ll take a closer look at template expressions and statements.
+
.l-main-section
:marked
## Template Expressions
- We saw a template expression within the interpolation braces.
- We’ll see template expressions again in [Property Bindings](#property-binding) (`[property]="expression"`) and
- [Event Bindings](#event-binding) (`(event)="expression"`).
-
- A template expression is a JavaScript-like expression. Many JavaScript expressions are legal template expressions but not all and there are a few language extensions. Notable differences include:
- * Assignment is prohibited except in [Event Bindings](#event-binding).
- * The `new` operator is prohibited.
- * The bit-wise operators, `|` and `&`, are not supported.
- * Increment and decrement operators, `++` and `--`, aren’t supported.
- * [Template expression operators](#expression-operators), such as `|` and `?.`, add new meaning.
-
+ A template **expression** produces a value.
+ Angular executes the expression and assigns it to property of a binding target such
+ as an HTML element, a component, or a directive.
+
+ We put a template expression within the interpolation braces when we wrote `{{1 + 1}}`.
+ We’ll see template expressions again in [Property Bindings](#property-binding) ,
+ appearing in quotes to the right of the (=) symbol as in `[property]="expression"`.
+
+ We write template expressions in a language that looks like JavaScript.
+ Many JavaScript expressions are legal template expressions but not all.
+ JavaScript expressions that have or promote side-effects are prohibited including:
+ * assignment (`=`)
+ * the `new` operator
+ * chaining expressions with `;` or `,`
+ * increment and decrement operators, `++` and `--`.
+
+ Other notable differences from JavaScript syntax include:
+ * no support for the bit-wise operators, `|` and `&`
+ * new [template expression operators](#expression-operators), such as `|` and `?.`
+
+
+ ### Expression Context
+
Perhaps more surprising, we cannot refer to anything in the global namespace.
- We can’t refer to `window` or `document`. We can’t call `console.log`.
+ We can’t refer to `window` or `document`. We can’t call `console.log` or `Math.max`.
We are restricted to referencing members of the expression context.
+
+ The *expression context* is typically the **component instance**, the source of binding values.
- The **expression context** is typically the **component instance** supporting a particular template instance.
-.l-sub-section
- :marked
- We speak of component and template ***instances***. Angular creates multiple concrete instances from a component class and its template.
-
- For example, we may define a component and template to display a list item and tell Angular to create new instances of that component/template pair for each item in a list. There’s a separate, independent expression context for each item in that list as well.
-
-:marked
- When we see `title` wrapped in double-curly braces,
{{ }}
.,
- we know that it is a property of a parent component.
- When we see `[disabled]="isUnchanged"` or `(click)="onCancel()”`,
- we know we are referring to that component's `isUnchanged` property and `onCancel` method respectively.
+ When we see *title* wrapped in double-curly braces,
{{title}}
,
+ we know that `title` is a property of the data-bound component.
+ When we see *isUnchanged* in `[disabled]="isUnchanged"`,
+ we know we are referring to that component's `isUnchanged` property.
The component itself is usually the expression *context* in which case
the template expression usually references that component.
+
The expression context may include an object other than the component.
-
- A [local template variable](#local-vars) is one such supplemental context object;
- we’ll discuss that option below.
-
- Another is the **`$event`** variable that contains information about an event raised on an element;
- we’ll talk about that when we consider [Event Bindings](#event-binding).
+ A [local template variable](#local-vars) is one such alternative context object.
+
+
+
+ ### Expression Guidelines
+ Template expressions can make or break an application.
+ Please follow these guidelines unless you have an exceptionally good reason to break them
+ in specific circumstances that you thoroughly understand.
+
+ #### No visible side-effects
+
+ A template expression should have ***no visible side-effects***.
+ We're not allowed to change any application state other than the value of the
+ target property.
+
+ This rule is essential to Angular's "unidirectional data flow" policy.
+ We should never worry that reading a component value might change some other displayed value.
+ The view should be stable throughout a single rendering pass.
+
+ #### Finish fast
+ Angular executes template expressions more often than we might think.
+ Expressions should finish quickly or the user experience may drag, especially on slower devices.
+
+ #### Keep them simple
+ Although we can write quite complex template expressions, we strongly discourage that practice.
+ Most readers frown on JavaScript in the HTML.
+ A property name or method call should be the norm.
+ An occasional Boolean negation (`!`) is OK.
+ Otherwise, confine application and business logic to the component itself where it will be easier to develop and test.
+
+ #### Idempotent Expressions
+ An [idempotent](https://en.wikipedia.org/wiki/Idempotence) expression is ideal because
+ it is free of side-effects and improves Angular's change detection performance.
+
+ In Angular terms, an idempotent expression always returns *exactly the same thing* until
+ one of its dependent values changes.
+
+ Dependent values should not change during a single turn of the JavaScript virtual machine.
+ If an idempotent expression returns a string or a number, it returns the same string or number
+ when called twice in a row. If the expression returns an object (including a `Date` or `Array`),
+ it returns the same object *reference* when called twice in a row.
+
+
+.l-main-section
+:marked
+ ## Template Statements
+
+ A template **statement** responds to an ***event*** raised by a binding target
+ such as an element, component, or directive.
+
+ We’ll see template statements in [Event Bindings](#event-binding),
+ appearing in quotes to the right of the (=) symbol as in `(event)="statement"`.
+
+ A template statement *has a side-effect*.
+ It's how we update application state from user input.
+ There would be no point to responding to an event otherwise.
+.l-sub-section
+ :marked
+ Responding to events is the other side of Angular's "unidirectional data flow".
+ We're free to change anything, anywhere, during this turn of the JavaScript virtual machine.
+:marked
+ Angular template statements are also written in a language that looks like JavaScript.
+ The template statement parser is different than the template expression parser and
+ specifically supports both assignment (=) and chaining expressions with semicolons (;) and commas (,).
+
+ However, certain JavaScript syntax is not allowed:
+ * the `new` operator
+ * increment and decrement operators, `++` and `--`
+ * bit-wise operators, `|` and `&`
+ * the [template expression operators](#expression-operators)
+
+ As with expressions, we cannot refer to anything in the global namespace.
+ We can’t refer to `window` or `document`. We can’t call `console.log` or `Math.max`.
+
+ We are restricted to referencing members of the statement context.
+ The **statement context** is typically the **component instance** to which we are binding an event.
+
+ The *onSave* in `(click)="onSave()"` is sure to be a method of the data-bound component instance.
+
+ The statement context may include an object other than the component.
+ A [local template variable](#local-vars) is one such alternative context object.
+ We'll frequently see the reserved `$event` symbol in event binding statements,
+ representing the "message" or "payload" of the raised event.
.l-sub-section
:marked
- Although we can write quite complex template expressions, we strongly discourage that practice. Most readers frown on JavaScript in the HTML. A property name or method call should be the norm. An occasional Boolean negation (`!`) is OK. Otherwise, confine application and business logic to the component itself where it will be easier to develop and test.
+ Although we can write quite complex template statements, we strongly discourage that practice.
+ Most readers frown on JavaScript in the HTML.
+ A method call or simple property assignment should be the norm.
:marked
- Now that we have a feel for template expressions, we’re ready to learn about the varieties of data binding syntax beyond Interpolation.
-
+ Now that we have a feel for template expressions and statements,
+ we’re ready to learn about the varieties of data binding syntax beyond Interpolation.
.l-main-section
:marked
## Binding syntax overview
- Data binding is a mechanism for coordinating what users see with application data values. While we could push values to and pull values from HTML,
+ Data binding is a mechanism for coordinating what users see with application data values.
+ While we could push values to and pull values from HTML,
the application is easier to write, read, and maintain if we turn these chores over to a binding framework.
- We simply declare bindings between the HTML and the data properties and let the framework do the work.
+ We simply declare bindings between binding sources and target HTML elements and let the framework do the work.
Angular provides many kinds of data binding and we’ll discuss each of them in this chapter.
First we'll take a high level view of Angular data binding and its syntax.
- We can group all bindings into three categories by the direction in which data flows. Each category has its distinctive syntax:
+ We can group all bindings into three categories by the direction in which data flows.
+ Each category has its distinctive syntax:
table
tr
th Data Direction
@@ -165,8 +256,8 @@ table
td One way
from view target
to data source
td
code-example(format="" ).
- (target) = "expression"
- on-target = "expression"
+ (target) = "statement"
+ on-target = "statement"
td Event
tr
td Two way
@@ -176,10 +267,8 @@ table
bindon-target = "expression"
td Two-way
:marked
- **Template expressions must be surrounded in quotes**
- except for interpolation expressions which must not be quoted.
-
- All binding types except interpolation have a **target name** to the left of the equal sign, either surrounded by punctuation (`[]`, `()`) or preceded by a prefix (`bind-`, `on-`, `bindon-`).
+ Binding types other than interpolation have a **target name** to the left of the equal sign,
+ either surrounded by punctuation (`[]`, `()`) or preceded by a prefix (`bind-`, `on-`, `bindon-`).
What is that target? Before we can answer that question, we must challenge ourselves to look at Template HTML in a new way.
@@ -187,8 +276,8 @@ table
With all the power of data binding and our ability to extend the HTML vocabulary
with custom markup, it is tempting to think of Template HTML as “HTML Plus”.
- Well it is “HTML Plus”.
-
+
+ *Well it is HTML Plus*.
But it’s also significantly different than the HTML we’re used to.
We really need a new mental model.
@@ -214,7 +303,7 @@ table
Our intuition is wrong! Our everyday HTML mental model is misleading us.
In fact, once we start data binding, we are no longer working with HTML *attributes*. We aren't setting attributes.
- We are setting the *properties* of DOM elements, Components, and Directives.
+ We are setting the *properties* of DOM elements, components, and directives.
.l-sub-section
:marked
@@ -336,7 +425,8 @@ table
.l-main-section
:marked
## Property Binding
- We write a template **Property Binding** when we want to set a property of a view element to the value of a template expression.
+ We write a template **Property Binding** when we want to set a property of a view element to the value of
+ a [template expression](#template-expressions).
The most common Property Binding sets an element property to a component property value as when
we bind the source property of an image element to the component’s `heroImageUrl` property.
@@ -352,8 +442,26 @@ table
for parent and child components to communicate)
+makeExample('template-syntax/ts/app/app.component.html', 'property-binding-4')(format=".")
:marked
- People often describe Property Binding as “one way data binding” because it can flow a value in one direction, from a component’s data property to an element property.
+ ### One-way *in*
+ People often describe property binding as *one way data binding* because it flows a value in one direction,
+ from a component’s data property into a target element property.
+
+ We cannot use property binding to pull values *out* of the target element.
+ We can't bind to a property of the target element to read it. We can only set it.
+
+.l-sub-section
+ :marked
+ Nor can we use property binding to *call* a method on the target element.
+
+ If the element raises events we can listen to them with an [event binding](#event-binding).
+
+ If we must read a target element property or call one of its methods,
+ we'll need a different technique.
+ See the API reference for
+ [viewChild](../api/core/ViewChild-var.html) and
+ [contentChild](../api/core/ContentChild-var.html).
+:marked
### Binding Target
A name between enclosing square brackets identifies the target property. The target property in this example is the image element’s `src` property.
@@ -527,11 +635,12 @@ code-example(format="", language="html").
keystrokes, mouse movements, clicks and touches.
We declare our interest in user actions through Angular Event Binding.
+ Event Binding syntax consists of a target event within parentheses on the left of an equal sign and a quoted
+ [**template statement**](#template-statements) on the right.
+
The following Event Binding listens for the button’s click event and calls the component's `onSave()` method:
+makeExample('template-syntax/ts/app/app.component.html', 'event-binding-1')(format=".")
:marked
- Event Binding syntax consists of a target event on the left of an equal sign and a template expression on the right: `(click)="onSave()"`
-
### Binding target
A **name between enclosing parentheses** identifies the target event. In the following example, the target is the button’s click event.
+makeExample('template-syntax/ts/app/app.component.html', 'event-binding-1')(format=".")
@@ -546,11 +655,11 @@ code-example(format="", language="html").
If the name fails to match an element event or an output property of a known directive,
Angular reports an “unknown directive” error.
- ### $event and event handling expressions
+ ### $event and event handling statements
In an Event Binding, Angular sets up an event handler for the target event.
- When the event is raised, the handler executes the template expression.
- The template expression typically involves a receiver that wants to do something
+ When the event is raised, the handler executes the template statement.
+ The template statement typically involves a receiver that wants to do something
in response to the event such as take a value from the HTML control and store it
in a model.
@@ -565,7 +674,7 @@ code-example(format="", language="html").
+makeExample('template-syntax/ts/app/app.component.html', 'without-NgModel')(format=".")
:marked
We’re binding the input box `value` to a `firstName` property and we’re listening for changes by binding to the input box’s `input` event.
- When the user makes changes, the `input` event is raised, and the binding executes the expression within a context that includes the DOM event object, `$event`.
+ When the user makes changes, the `input` event is raised, and the binding executes the statement within a context that includes the DOM event object, `$event`.
We must follow the `$event.target.value` path to get the changed text so we can update the `firstName`
@@ -578,19 +687,19 @@ code-example(format="", language="html").
Now imagine a parent component that listens for that event with an Event Binding.
+makeExample('template-syntax/ts/app/app.component.html', 'event-binding-to-component')(format=".")
:marked
- The event binding surfaces the *hero-to-delete* emitted by `HeroDetail` to the expression via the `$event` variable.
+ The event binding surfaces the *hero-to-delete* emitted by `HeroDetail` to the statement via the `$event` variable.
We pass it along to the parent `onHeroDeleted()` method.
That method presumably knows how to delete the hero.
- Evaluation of an Event Binding template expression may have side-effects as this one clearly does.
- They are not just OK (unlike in property bindings); they are expected.
+ Evaluation of this Event Binding template statement has a side-effect. It deletes a hero.
+ Side-effects are not just OK; they are expected.
- The expression could update the model thereby triggering other changes that percolate through the system, changes that
+ The statement could update the model thereby triggering other changes that percolate through the system, changes that
are ultimately displayed in this view and other views.
The event processing may result in queries and saves to a remote server. It's all good.
### Event bubbling and propagation
- Angular invokes the event-handling expression if the event is raised by the current element or one of its child elements.
+ Angular invokes the event-handling statement if the event is raised by the current element or one of its child elements.
+makeExample('template-syntax/ts/app/app.component.html', 'event-binding-bubbling')(format=".")
:marked
Many DOM events, both [native](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Overview_of_Events_and_Handlers ) and [custom](https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events ), “bubble” events up their ancestor tree of DOM elements until an event handler along the way prevents further propagation.
@@ -600,16 +709,16 @@ code-example(format="", language="html").
`EventEmitter` events don’t bubble.
:marked
- The result of an Event Binding expression determines if
+ The result of an Event Binding statement determines if
[event propagation](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Examples#Example_5:_Event_Propagation)
continues or stops with the current element.
- Event propagation stops if the binding expression returns a falsey value (as does a method with no return value).
+ Event propagation stops if the binding statement returns a falsey value (as does a method with no return value).
Clicking the button in this next example triggers a save;
the click doesn't make it to the outer `
` so it's save is not called:
+makeExample('template-syntax/ts/app/app.component.html', 'event-binding-no-propagation')(format=".")
:marked
- Propagation continues if the expression returns a truthy value. The click is heard both by the button
+ Propagation continues if the statement returns a truthy value. The click is heard both by the button
and the outer `
`, causing a double save:
+makeExample('template-syntax/ts/app/app.component.html', 'event-binding-propagation')(format=".")
@@ -622,6 +731,12 @@ code-example(format="", language="html").
The `NgModel` directive serves that purpose as seen in this example:
+makeExample('template-syntax/ts/app/app.component.html', 'NgModel-1')(format=".")
+.callout.is-important
+ header
+ :marked
+
[()] = banana in a box
+ :marked
+ To remember that the parentheses go inside the brackets, visualize a *banana in a box*.
:marked
If we prefer the “canonical” prefix form to the punctuation form, we can write
+makeExample('template-syntax/ts/app/app.component.html', 'NgModel-2')(format=".")
@@ -844,6 +959,9 @@ figure.image-display
+makeExample('template-syntax/ts/app/app.component.html', 'NgFor-3')(format=".")
:marked
+.l-sub-section
+ :marked
+ Learn about other special values such as `last`, `even` and `odd` in the [API](../api/common/NgFor-directive.html) guide.
@@ -980,30 +1098,33 @@ figure.image-display
:marked
## Input and Output Properties
We can only bind to **target directive** properties that are either **inputs** or **outputs**.
+
+.alert.is-important
+ :marked
+ A *component is a directive*. We use the terms "directive" and "component" interchangeably.
.l-sub-section
:marked
We're drawing a sharp distinction between a data binding **target** and a data binding **source**.
- The target is to the *left* of the (=) in a binding expression.
- The source is on the *right* of the (=).
-
- Every member of a **source** directive (typically a component) is automatically available for binding.
- We don't have to do anything special to access a component member in the quoted template expression
- to the right of the (=).
+ The *target* of a binding is to the *left* of the (=).
+ The *source* is on the *right* of the (=).
+
+ The *target* of a binding is the property or event inside the binding punctuation: `[]`, `()` or `[()]`.
+ The *source* is either inside quotes (") or within an interpolation (`{}`).
- We have *limited* access to members of a **target** directive (typically a component).
- We can only bind to *input* and *output* properties of target components to the left of the (=).
+ Every member of a **source** directive or component is automatically available for binding.
+ We don't have to do anything special to access a component member in a template expression or statement.
- Also remember that a *component is a directive*.
- In this section, we use the terms "directive" and "component" interchangeably.
+ We have *limited* access to members of a **target** directive or component.
+ We can only bind to properties that are explicitly identified as *inputs* and *outputs*.
:marked
- In this chapter we’ve focused mainly on binding to component members within template expressions
- on the *right side of the binding declaration*.
- A member in that position is a binding “data source”. It's not a target for binding.
+ In this chapter we’ve focused mainly on binding to component members within template expressions and statements
+ that appear on the *right side of the binding declaration*.
+ A member in that position is a binding “data source”.
In the following example, `iconUrl` and `onSave` are members of the `AppComponent`
- referenced within template expressions to the *right* of the (=).
+ referenced within quoted syntax to the right of the (=).
+makeExample('template-syntax/ts/app/app.component.html', 'io-1')(format=".")
:marked
They are *neither inputs nor outputs* of `AppComponent`. They are data sources for their bindings.
@@ -1011,16 +1132,13 @@ figure.image-display
Now look at the `HeroDetailComponent` when it is the **target of a binding**.
+makeExample('template-syntax/ts/app/app.component.html', 'io-2')(format=".")
:marked
- Both `HeroDetail.hero` and `HeroDetail.deleted` are on the **left side** of binding expressions.
- `HeroDetail.hero` is the target of a Property Binding. `HeroDetail.deleted` is the target of an Event Binding.
-
-
- **Data flow *into* the `HeroDetail.hero` target property** from the template expression.
- Therefore `HeroDetail.hero` is an ***input*** property from the perspective of `HeroDetail`.
-
- **Events stream *out* of the `HeroDetail.deleted` target property** and toward the receiver within the template expression.
- Therefore `HeroDetail.deleted` is an ***output*** property from the perspective of `HeroDetail`.
-
+ Both `HeroDetail.hero` and `HeroDetail.deleted` are on the **left side** of binding declarations.
+ `HeroDetail.hero` is inside brackets; it is the target of a Property Binding.
+ `HeroDetail.deleted` is inside parentheses; it is the target of an Event Binding.
+
+ ### Declaring input and output properties
+ Target properties must be explicitly marked as inputs or outputs.
+
When we peek inside `HeroDetailComponent` we see that these properties are marked
with decorators as input and output properties.
+makeExample('template-syntax/ts/app/hero-detail.component.ts', 'input-output-1')(format=".")
@@ -1035,9 +1153,22 @@ figure.image-display
We can specify an input/output property with a decorator or in one the metadata arrays.
Don't do both!
:marked
+ ### Input or Output?
+
+ *Input* properties usually receive data values.
+ *Output* properties expose event producers (e.g, an `EventEmitter`).
+
+ The terms "input" and "output" reflect the perspective of the target directive.
+
+ `HeroDetail.hero` is an ***input*** property from the perspective of `HeroDetailComponent`
+ because data flow *into* that property from a template binding expression.
+
+ `HeroDetail.deleted` is an ***output*** property from the perspective of `HeroDetailComponent`
+ because events stream *out* of that property and toward the handler in a template binding statement.
+
### Aliasing input/output properties
- Sometimes we want the public name of the property to be different from the internal name.
+ Sometimes we want the public name of an input/output property to be different from the internal name.
This is frequently the case with [Attribute Directives](attribute-directives.html).
Directive consumers expect to bind to the name of the directive.
@@ -1045,14 +1176,23 @@ figure.image-display
The directive name is often a poor choice for the the internal property name
because it rarely describes what the property does.
- The corresponding `MyClickDirective` internal property is called `clicks`.
+ `myClick` is not a good name for a property that emits click events.
- Fortunately, we can alias the internal name to meet the conventional needs of the directive's consumer.
- We alias in decorator syntax like this:
+ Fortunately, we can have a public name for the property that meets conventional expectations
+ and use a different name internally
+ by providing a public alias for the internal property name in the decorator like this:
+makeExample('template-syntax/ts/app/my-click.directive.ts', 'my-click-output-1')(format=".")
+:marked
+ Now the directive name, `myClick`, is the public facing property name to which we can bind
++makeExample('template-syntax/ts/app/app.component.html', 'my-click')(format=".")
+:marked
+ while inside the directive, the property is known as `clicks`.
+
+ With aliasing we please both the directive consumer and the directive author.
.l-sub-section
:marked
- The equivalent aliasing with the `outputs` array requires a colon-delimited string with
+ We can alias property names in the `inputs` and `outputs` arrays as well.
+ We write a colon-delimited string with
the internal property name on the left and the public name on the right:
+makeExample('template-syntax/ts/app/my-click.directive.ts', 'my-click-output-2')(format=".")
diff --git a/public/news.jade b/public/news.jade
new file mode 100644
index 0000000000..36ec162b2d
--- /dev/null
+++ b/public/news.jade
@@ -0,0 +1,86 @@
+.grid-fluid.l-space-bottom-4
+ .c12.text-center
+ h3.text-headline.text-uppercase From the Core Team
+ .clear
+
+.grid-fluid
+ .c6
+ .article-card
+ .date January 11, 2016
+ .title
+ a(
+ target="_blank"
+ href="http://angularjs.blogspot.com/2016/01/angular-2-mit-open-source-licensed.html"
+ ) Angular 2: an MIT Open Source Licensed Framework
+ p As of beta.2 this week, we're moving Angular 2, its related libraries, and any code snippets and examples to the MIT license. Open source licenses are meant to protect developers by making it clear how code can be used. We want developers to be confident that they can use, fork...
+ img(src="/resources/images/bios/naomi.jpg")
+ .posted Posted by
Naomi Black
+ .c6
+ .article-card
+ .date December 15, 2015
+ .title
+ a(
+ target="_blank"
+ href="http://angularjs.blogspot.com/2015/12/angular-2-beta.html"
+ ) Angular 2 Beta
+ p We're ecstatic to announce that we've reached Angular 2 Beta. You can read about many of the improvements over Angular 1 in a recent post. Get started learning Angular 2 now at angular.io. What does 'beta' mean? Beta means we're now confident that most developers can be successful building large applications using Angular 2....
+
+ .author
+ img(src="/resources/images/bios/brad-green.jpg")
+ .posted Posted by
Brad Green
+
+.grid-fluid.l-space-top-6
+ .c12.text-center
+ h3.text-headline.text-uppercase From Our Developer Community
+ .clear
+
+ .grid-fluid.l-space-bottom-2.l-space-top-4
+ .c6
+ .article-card
+ .date January 6, 2016
+ .title
+ a(
+ target="_blank"
+ href="http://blog.thoughtram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html"
+ ) Taking advantage of Observables in Angular 2
+ p Some people seem to be confused why Angular 2 seems to favor the Observable abstraction over the Promise abstraction when it comes to dealing with async behavior. There are pretty good resources about the difference between Observables and Promises already out there.
+ .author
+ img(src="/resources/images/bios/shield-bio-placeholder.png")
+ .posted Posted by
Christoph Burgdorf
+ .c6
+ .article-card
+ .date December 30, 2015
+ .title
+ a(
+ target="_blank"
+ href="https://medium.com/google-developer-experts/angular-2-introduction-to-redux-1cf18af27e6e#.fs370dms1"
+ ) Angular 2 — Introduction to Redux
+ p How to use Redux in Angular 2 Applications. Redux, now in version 3, has been around less than a year but it has proved very successful. Inspired by Flux and Elm, is used to handle Application state and bind it to the User Interface in a very effective way. Redux also enables cool features
+ .author
+ img(src="/resources/images/bios/angular-gde-bio-placeholder.png")
+ .posted Posted by
Gerard Sans
+.grid-fluid.l-space-bottom-4
+ .c6
+ .article-card
+ .date December 17, 2015
+ .title
+ a(
+ target="_blank"
+ href="http://wassimchegham.com/blog/angularjs-explique-en-patrons-de-conception-design-pattern-episode-6-module-data-mapper-observer-service"
+ ) AngularJS expliqué en patrons de conception
+ p Dans ce dernier épisode, nous allons voir comment des patrons de conception tels que le Module Pattern ou l’Observer sont utilisés dans AngularJS. Cet article fait partie d’une série d’articles consacrés à l’utilisation des patrons de conceptions par et dans les composants d’AngularJS...
+ .author
+ img(src="/resources/images/bios/angular-gde-bio-placeholder.png")
+ .posted Posted by
Wassim Chegham
+ .c6
+ .article-card
+ .date November 23, 2015
+ .title
+ a(
+ target="_blank"
+ href="http://blog.thoughtram.io/angular2/2015/11/23/multi-providers-in-angular-2.html"
+ ) Multi Providers in Angular 2
+ p The new dependency injection system in Angular 2 comes with a feature called “Multi Providers” that basically enable us, the consumer of the platform, to hook into certain operations and plug in custom functionality we might need in our application
+ .author
+ img(src="/resources/images/bios/angular-gde-bio-placeholder.png")
+ .posted Posted by
Pascal Precht
\ No newline at end of file
diff --git a/public/resources/css/main.scss b/public/resources/css/main.scss
index cf74704075..f79ec2fc3a 100644
--- a/public/resources/css/main.scss
+++ b/public/resources/css/main.scss
@@ -46,6 +46,8 @@
@import 'module/api';
@import 'module/cheatsheet';
@import 'module/filetree';
+@import 'module/support';
+@import 'module/article-card';
/*
diff --git a/public/resources/css/module/_article-card.scss b/public/resources/css/module/_article-card.scss
new file mode 100644
index 0000000000..dcc3e5e340
--- /dev/null
+++ b/public/resources/css/module/_article-card.scss
@@ -0,0 +1,52 @@
+.article-card {
+ margin: 0px 0px ($unit * 4) 0px;
+ padding: ($unit * 2);
+ background: lighten($mist, 3%);
+ border-radius: ($unit / 2);
+ min-height: 330px;
+ position: relative;
+ @media handheld and (max-width: $phone-breakpoint),
+ screen and (max-device-width: $phone-breakpoint),
+ screen and (max-width: $tablet-breakpoint) {
+ padding: ($unit * 2) ($unit * 1);
+ }
+ a {
+ text-decoration: none;
+ }
+ strong {
+ color: darken($darkgrey, 5%);
+ font-weight: 400;
+ }
+ &:last-child {
+ margin: 0;
+ }
+ .date {
+ text-transform: uppercase;
+ margin-bottom: $unit;
+ }
+ .title {
+ font-size: 20px;
+ color: $regal;
+ }
+ p, .date {
+ font-size: 16px;
+ color: darken($darkgrey, 5%);
+ }
+ .posted {
+ color: $bismark;
+ font-size: 16px;
+ display: inline;
+ padding-left: 10px;
+ }
+ img {
+ width: 40px;
+ height: 40px;
+ border-radius: 50% 50%;
+ display: inline;
+ vertical-align: middle;
+ }
+ .author {
+ position: absolute;
+ bottom: 20px;
+ }
+}
diff --git a/public/resources/css/module/_support.scss b/public/resources/css/module/_support.scss
new file mode 100644
index 0000000000..1fb1e1472e
--- /dev/null
+++ b/public/resources/css/module/_support.scss
@@ -0,0 +1,18 @@
+.support-content {
+ a {
+ text-decoration: none;
+ margin: 10px 0px;
+ }
+ .c8 {
+ padding-top: 30px;
+ }
+ .grid-fluid {
+ margin: 20px 0px;
+ }
+ hr {
+ border: 0;
+ color: #ECEFF1;
+ background-color: #ECEFF1;
+ height: 1.5px;
+ }
+}
diff --git a/public/resources/images/bios/angular-gde-bio-placeholder.png b/public/resources/images/bios/angular-gde-bio-placeholder.png
new file mode 100644
index 0000000000..d84b3149f9
Binary files /dev/null and b/public/resources/images/bios/angular-gde-bio-placeholder.png differ
diff --git a/public/resources/images/bios/kara-erickson.jpg b/public/resources/images/bios/kara-erickson.jpg
new file mode 100644
index 0000000000..e7cafc797b
Binary files /dev/null and b/public/resources/images/bios/kara-erickson.jpg differ
diff --git a/public/resources/images/bios/shield-bio-placeholder.png b/public/resources/images/bios/shield-bio-placeholder.png
new file mode 100644
index 0000000000..d3bd434080
Binary files /dev/null and b/public/resources/images/bios/shield-bio-placeholder.png differ
diff --git a/public/resources/images/logos/standard/angular-gde-logo@2x.png b/public/resources/images/logos/standard/angular-gde-logo@2x.png
new file mode 100644
index 0000000000..2aaa3a469d
Binary files /dev/null and b/public/resources/images/logos/standard/angular-gde-logo@2x.png differ
diff --git a/public/resources/images/support/angular-gde-logo.png b/public/resources/images/support/angular-gde-logo.png
new file mode 100644
index 0000000000..5702afacab
Binary files /dev/null and b/public/resources/images/support/angular-gde-logo.png differ
diff --git a/public/resources/images/support/github-logo.png b/public/resources/images/support/github-logo.png
new file mode 100644
index 0000000000..5e8932b099
Binary files /dev/null and b/public/resources/images/support/github-logo.png differ
diff --git a/public/resources/images/support/gitter-logo.png b/public/resources/images/support/gitter-logo.png
new file mode 100644
index 0000000000..b53984ec91
Binary files /dev/null and b/public/resources/images/support/gitter-logo.png differ
diff --git a/public/resources/images/support/stackoverflow-logo.png b/public/resources/images/support/stackoverflow-logo.png
new file mode 100644
index 0000000000..f10564a8ec
Binary files /dev/null and b/public/resources/images/support/stackoverflow-logo.png differ
diff --git a/public/support.jade b/public/support.jade
new file mode 100644
index 0000000000..6c2c7b1564
--- /dev/null
+++ b/public/support.jade
@@ -0,0 +1,36 @@
+.support-content
+ .grid-fluid
+ .c4
+ figure
+ img(src="/resources/images/support/stackoverflow-logo.png" alt="Us" style="width:240px;")
+ .c8
+ p
angular2
+ p
angular2-forms
+ p
angular2-template
+
+ hr
+
+ .grid-fluid
+ .c4
+ figure
+ img(src="/resources/images/support/gitter-logo.png" alt="Us" style="width:240px;")
+ .c8
+ p Community driven
real time chat
+
+ //
+ hr
+ .grid-fluid
+ .c4
+ figure
+ img(src="/resources/images/support/angular-gde-logo.png" alt="Us" style="width:240px;")
+ .c8
+ p Are you looking for an Angular expert? Our experts provide various types of consulting, training, and other services. You can find our awesome GDEs on our
Angular GDE page.
+
+ hr
+
+ .grid-fluid
+ .c4
+ figure
+ img(src="/resources/images/support/github-logo.png" alt="Us" style="width:240px;" )
+ .c8
+ p File Angular 2 issues at our
GitHub Repository