From 40312da5b0c9f51d93b6cc5e8df63a0d25768f1f Mon Sep 17 00:00:00 2001 From: Tom Ingebretsen Date: Sat, 5 Dec 2015 18:35:03 -0700 Subject: [PATCH] docs(guide): add Dart intro closes #460 --- .../dart/lib/backend_service.dart | 25 + .../_examples/architecture/dart/lib/hero.dart | 13 + .../dart/lib/hero_detail_component.dart | 11 + .../dart/lib/hero_detail_component.html | 9 + .../dart/lib/hero_list_component.dart | 38 ++ .../dart/lib/hero_list_component.html | 8 + .../dart/lib/hero_list_component_1.html | 10 + .../architecture/dart/lib/hero_service.dart | 20 + .../architecture/dart/lib/logger_service.dart | 18 + .../_examples/architecture/dart/pubspec.yaml | 10 + .../architecture/dart/web/index.html | 11 + .../_examples/architecture/dart/web/main.dart | 12 + public/docs/dart/latest/_data.json | 2 +- public/docs/dart/latest/guide/_data.json | 6 +- .../docs/dart/latest/guide/architecture.jade | 452 ++++++++++++++++++ .../dart/latest/guide/displaying-data.jade | 3 + public/docs/dart/latest/guide/index.jade | 99 +++- public/docs/dart/latest/guide/setup.jade | 168 ------- public/docs/dart/latest/guide/user-input.jade | 1 + 19 files changed, 736 insertions(+), 180 deletions(-) create mode 100644 public/docs/_examples/architecture/dart/lib/backend_service.dart create mode 100644 public/docs/_examples/architecture/dart/lib/hero.dart create mode 100644 public/docs/_examples/architecture/dart/lib/hero_detail_component.dart create mode 100644 public/docs/_examples/architecture/dart/lib/hero_detail_component.html create mode 100644 public/docs/_examples/architecture/dart/lib/hero_list_component.dart create mode 100644 public/docs/_examples/architecture/dart/lib/hero_list_component.html create mode 100644 public/docs/_examples/architecture/dart/lib/hero_list_component_1.html create mode 100644 public/docs/_examples/architecture/dart/lib/hero_service.dart create mode 100644 public/docs/_examples/architecture/dart/lib/logger_service.dart create mode 100644 public/docs/_examples/architecture/dart/pubspec.yaml create mode 100644 public/docs/_examples/architecture/dart/web/index.html create mode 100644 public/docs/_examples/architecture/dart/web/main.dart create mode 100644 public/docs/dart/latest/guide/architecture.jade delete mode 100644 public/docs/dart/latest/guide/setup.jade diff --git a/public/docs/_examples/architecture/dart/lib/backend_service.dart b/public/docs/_examples/architecture/dart/lib/backend_service.dart new file mode 100644 index 0000000000..bc3d0db676 --- /dev/null +++ b/public/docs/_examples/architecture/dart/lib/backend_service.dart @@ -0,0 +1,25 @@ +// #docregion +library developer_guide_intro.backend_service; + +import 'package:angular2/angular2.dart'; +import 'package:developer_guide_intro/logger_service.dart'; +import 'package:developer_guide_intro/hero.dart'; + +@Injectable() +class BackendService { + final Logger _logger; + List getAll(type) { + // TODO get from the database and return as a promise + if (type == Hero) { + return [ + new Hero('Windstorm', power: 'Weather mastery'), + new Hero('Mr. Nice', power: 'Killing them with kindness'), + new Hero('Magneta', power: 'Manipulates metalic objects') + ]; + } + _logger.error('Cannot get object of this type'); + throw new ArgumentError("TODO: put log content here"); + } + + BackendService(Logger this._logger); +} diff --git a/public/docs/_examples/architecture/dart/lib/hero.dart b/public/docs/_examples/architecture/dart/lib/hero.dart new file mode 100644 index 0000000000..4cbe6c7486 --- /dev/null +++ b/public/docs/_examples/architecture/dart/lib/hero.dart @@ -0,0 +1,13 @@ +// #docregion +library developer_guide_intro.hero; + +class Hero { + static int _nextId = 1; + int id; + String name; + String power; + + Hero(this.name, {this.power}) { + id = _nextId++; + } +} diff --git a/public/docs/_examples/architecture/dart/lib/hero_detail_component.dart b/public/docs/_examples/architecture/dart/lib/hero_detail_component.dart new file mode 100644 index 0000000000..920de097f4 --- /dev/null +++ b/public/docs/_examples/architecture/dart/lib/hero_detail_component.dart @@ -0,0 +1,11 @@ +// #docregion +library developer_guide_intro.hero_detail_component; + +import 'package:angular2/angular2.dart'; +import 'package:developer_guide_intro/hero.dart'; + +@Component(selector: 'hero-detail', templateUrl: 'hero_detail_component.html') +class HeroDetailComponent { + @Input() + Type hero = Hero; +} diff --git a/public/docs/_examples/architecture/dart/lib/hero_detail_component.html b/public/docs/_examples/architecture/dart/lib/hero_detail_component.html new file mode 100644 index 0000000000..7dde3107e4 --- /dev/null +++ b/public/docs/_examples/architecture/dart/lib/hero_detail_component.html @@ -0,0 +1,9 @@ +
+

{{hero.name}} Detail

+
Id: {{hero.id}}
+
Name: + +
+ +
Power: +
diff --git a/public/docs/_examples/architecture/dart/lib/hero_list_component.dart b/public/docs/_examples/architecture/dart/lib/hero_list_component.dart new file mode 100644 index 0000000000..188faad127 --- /dev/null +++ b/public/docs/_examples/architecture/dart/lib/hero_list_component.dart @@ -0,0 +1,38 @@ +// #docplaster +library developer_guide_intro.hero_list_component; + +import 'package:angular2/angular2.dart'; +import 'package:developer_guide_intro/hero.dart'; +import 'package:developer_guide_intro/hero_detail_component.dart'; +import 'package:developer_guide_intro/hero_service.dart'; + +// #docregion metadata +// #docregion providers +@Component( +// #enddocregion providers + selector: 'hero-list', + templateUrl: 'hero_list_component.html', + directives: const [HeroDetailComponent], +// #docregion providers + providers: const [HeroService]) +// #enddocregion providers +// #enddocregion metadata +/* +// #docregion metadata, providers +class HeroListComponent { ... } +// #enddocregion metadata, providers +*/ +// #docregion class +class HeroListComponent { + List heroes; + Hero selectedHero; +// #docregion ctor + HeroListComponent(HeroService heroService) { + heroes = heroService.getHeroes(); + } +// #enddocregion ctor + selectHero(Hero hero) { + selectedHero = hero; + } +} +// #enddocregion class diff --git a/public/docs/_examples/architecture/dart/lib/hero_list_component.html b/public/docs/_examples/architecture/dart/lib/hero_list_component.html new file mode 100644 index 0000000000..539ef5fdd5 --- /dev/null +++ b/public/docs/_examples/architecture/dart/lib/hero_list_component.html @@ -0,0 +1,8 @@ + +

Hero List

+ +
+ {{hero.name}} +
+ + diff --git a/public/docs/_examples/architecture/dart/lib/hero_list_component_1.html b/public/docs/_examples/architecture/dart/lib/hero_list_component_1.html new file mode 100644 index 0000000000..8673962169 --- /dev/null +++ b/public/docs/_examples/architecture/dart/lib/hero_list_component_1.html @@ -0,0 +1,10 @@ + +
{{hero.name}}
+ +
...
+ + + +
...
+ + diff --git a/public/docs/_examples/architecture/dart/lib/hero_service.dart b/public/docs/_examples/architecture/dart/lib/hero_service.dart new file mode 100644 index 0000000000..822311fa3a --- /dev/null +++ b/public/docs/_examples/architecture/dart/lib/hero_service.dart @@ -0,0 +1,20 @@ +library developer_guide_intro.hero_service; + +import 'package:angular2/angular2.dart'; +import 'package:developer_guide_intro/hero.dart'; +import 'package:developer_guide_intro/backend_service.dart'; +import 'package:developer_guide_intro/logger_service.dart'; + +// #docregion class +@Injectable() +class HeroService { + final BackendService _backendService; + final Logger _logger; + HeroService(Logger this._logger, BackendService this._backendService); + List getHeroes() { + List heroes = _backendService.getAll(Hero); + _logger.log('Got ${heroes.length} heroes from the server.'); + return heroes; + } +} +// #enddocregion class diff --git a/public/docs/_examples/architecture/dart/lib/logger_service.dart b/public/docs/_examples/architecture/dart/lib/logger_service.dart new file mode 100644 index 0000000000..813e4b89be --- /dev/null +++ b/public/docs/_examples/architecture/dart/lib/logger_service.dart @@ -0,0 +1,18 @@ +// #docregion +library developer_guide_intro.logger_service; + +import 'dart:html'; + +import 'package:angular2/angular2.dart'; + +/// A service for logging messages of various types. +/// +/// We could switch this implementation to use package:logging. +@Injectable() +class Logger { + void log(Object msg) => window.console.log(msg); + + void error(Object msg) => window.console.error(msg); + + void warn(Object msg) => window.console.warn(msg); +} diff --git a/public/docs/_examples/architecture/dart/pubspec.yaml b/public/docs/_examples/architecture/dart/pubspec.yaml new file mode 100644 index 0000000000..e56d6b115c --- /dev/null +++ b/public/docs/_examples/architecture/dart/pubspec.yaml @@ -0,0 +1,10 @@ +name: developer_guide_intro +description: Developer Guide Intro +version: 0.0.1 +dependencies: + angular2: 2.0.0-beta.0 + browser: ^0.10.0 +transformers: +- angular2: + platform_directives: 'package:angular2/src/common/directives.dart#CORE_DIRECTIVES' + entry_points: web/main.dart diff --git a/public/docs/_examples/architecture/dart/web/index.html b/public/docs/_examples/architecture/dart/web/index.html new file mode 100644 index 0000000000..c3d91bf64d --- /dev/null +++ b/public/docs/_examples/architecture/dart/web/index.html @@ -0,0 +1,11 @@ + + + + Intro to Angular 2 + + + + + Loading... + + diff --git a/public/docs/_examples/architecture/dart/web/main.dart b/public/docs/_examples/architecture/dart/web/main.dart new file mode 100644 index 0000000000..758988401d --- /dev/null +++ b/public/docs/_examples/architecture/dart/web/main.dart @@ -0,0 +1,12 @@ +// #docregion +import 'package:angular2/bootstrap.dart'; +import 'package:developer_guide_intro/backend_service.dart'; +import 'package:developer_guide_intro/hero_service.dart'; +import 'package:developer_guide_intro/logger_service.dart'; +import 'package:developer_guide_intro/hero_list_component.dart'; + +main() { + // #docregion bootstrap + bootstrap(HeroListComponent, [BackendService, HeroService, Logger]); + // #enddocregion bootstrap +} diff --git a/public/docs/dart/latest/_data.json b/public/docs/dart/latest/_data.json index 7cc6097c3d..6cd1f36402 100644 --- a/public/docs/dart/latest/_data.json +++ b/public/docs/dart/latest/_data.json @@ -13,7 +13,7 @@ "guide": { "icon": "list", - "title": "Step By Step Guide", + "title": "Developers Guide", "banner": "Angular 2 is currently in Beta." }, diff --git a/public/docs/dart/latest/guide/_data.json b/public/docs/dart/latest/guide/_data.json index 12fcf7ed9c..4d431a5f7a 100644 --- a/public/docs/dart/latest/guide/_data.json +++ b/public/docs/dart/latest/guide/_data.json @@ -2,15 +2,15 @@ "_listtype": "ordered", "index": { - "title": "Step By Step Guide" + "title": "Developers Guide" }, "cheatsheet": { "title": "Angular Cheat Sheet" }, - "setup": { - "title": "Getting Started" + "architecture": { + "title": "Architecture Overview" }, "displaying-data": { diff --git a/public/docs/dart/latest/guide/architecture.jade b/public/docs/dart/latest/guide/architecture.jade new file mode 100644 index 0000000000..3f6caca10b --- /dev/null +++ b/public/docs/dart/latest/guide/architecture.jade @@ -0,0 +1,452 @@ +include ../../../../_includes/_util-fns + +:marked + Angular 2 is a framework to help us build client applications in HTML and + either JavaScript or a language (like Dart or TypeScript) that compiles to JavaScript. + Angular 2 for Dart is published as the `angular2` package, which + (like many other Dart packages) is available via the Pub tool. + + With Angular, we write applications by composing HTML *templates* with Angularized markup, + writing *component* classes to manage those templates, adding application logic in *services*, + and handing the top root component to Angular's *bootstrapper*. + + Angular takes over, presenting our application content in a browser and responding to user interactions + according to the instructions we provided. + +figure + img(src="/resources/images/devguide/architecture/airplane.png" alt="Us" align="left" style="width:200px; margin-left:-40px;margin-right:10px" ) +:marked + Of course there is more to it than this. + We're cruising at high altitude in this overview. + We're looking for landmarks. We should expect the object below to be fuzzy and obscured by occasional clouds. + Details become more clear and precise when we land in the chapters themselves. +
+ +:marked + An Angular 2 for Dart application rests on seven main building blocks: + 1. [Components](#component) + 1. [Templates](#template) + 1. [Metadata](#metadata) + 1. [Data binding](#data-binding) + 1. [Directives](#directive) + 1. [Services](#service) + 1. [Dependency injection](#dependency-injection) + +figure + img(src="/resources/images/devguide/architecture/overview.png" alt="overview" style="margin-left:-40px;" width="700") +:marked + Learn these seven and we're on our way. + +.l-main-section + +:marked + ## Components +figure + img(src="/resources/images/devguide/architecture/hero-component.png" alt="Component" align="left" style="width:200px; margin-left:-40px;margin-right:10px" ) +:marked + A **component** controls a patch of screen real estate that we could call a *view*. + A set of navigation links, a list of heroes, a hero editor ... + they're all views controlled by components. + + We define a component's application logic — what it does to support the view — inside a class. + The class interacts with the view through an API of properties and methods. + + + A `HeroListComponent`, for example, might have a `heroes` property that returns an array of heroes + that it acquired from a service. + It might have a `selectHero()` method that sets a `selectedHero` property when the user clicks to choose a hero from that list. + The component might be a class like this: + ++makeExample('architecture/dart/lib/hero_list_component.dart', 'class', 'lib/hero_list_component.dart') +:marked + Angular creates, updates, and destroys components as the user moves through the application. + The developer can take action at each moment in this lifecycle through optional lifecycle hooks. + + +.l-sub-section + :marked + We may wonder who is calling the component's constructor? Who provides the service parameter? + For the moment, have faith that Angular will call the constructor and deliver an + appropriate `HeroService` when we need it. + +.l-main-section + +:marked + ## Templates +figure + img(src="/resources/images/devguide/architecture/template.png" alt="Template" align="left" style="width:200px; margin-left:-40px;margin-right:10px" ) +:marked + We define a component's view with its companion **template**. A template is a form of HTML + that tells Angular how to render the component. + + A template looks like regular HTML much of the time ... and then it gets a bit strange. Here is a + template for our `HeroListComponent`: ++makeExample('architecture/dart/lib/hero_list_component.html', null, 'lib/hero_list_component.html') +:marked + This template features typical HTML elements like `

` and `
`. + But what are `*ngFor`, {‌{hero.name}}, `(click)`, `[hero]`, and ``? + They're examples of Angular's template syntax. + We'll grow accustomed to that syntax and may even learn to love it. + + Take a look at the last line, + which has the `` tag. + That tag adds a custom element representing a component we haven't seen yet, + a `HeroDetailComponent`. + + The `HeroDetailComponent` is a *different* component than the `HeroListComponent` we've seen. + The `HeroDetailComponent` (code not shown) presents facts about a particular hero, the + hero that the user selects from the list presented by the the `HeroListComponent`. + The `HeroDetailComponent` is a **child** of the `HeroListComponent`. + +figure + img(src="/resources/images/devguide/architecture/component-tree.png" alt="Metadata" align="left" style="width:300px; margin-left:-40px;margin-right:10px" ) +:marked + Notice how `` rests comfortably among native HTML elements. + We can and _will_ mix our custom components with native HTML in the same layouts. + + In this manner we'll compose complex component trees to build out our richly featured application. +
+ +.l-main-section + +:marked + ## Metadata +figure + img(src="/resources/images/devguide/architecture/metadata.png" alt="Metadata" align="left" style="width:150px; margin-left:-40px;margin-right:10px" ) +:marked +

Metadata tells Angular how to process a class.

+
+:marked + [Looking back at the code](#component-code) for `HeroListComponent`, we see that it's just a class. + There is no evidence of a framework, no "Angular" in it at all. + + In fact, it really is *just a class*. It's not a component until we *tell Angular about it*. + + We tell Angular that `HeroListComponent` is a component by attaching **metadata** to the class. + + In Dart, we attach metadata by using an **annotation**. + Here's some metadata for `HeroListComponent`: + ++makeExample('architecture/dart/lib/hero_list_component.dart', 'metadata', 'lib/hero_list_component.dart') +:marked + Here we see the `@Component` annotation, which (no surprise) identifies the class + immediately below it as a component class. + + Annotations often have configuration parameters. + The `@Component` annotation takes parameters to provide the + information Angular needs to create and present the component and its view. + + Here we see a few of the possible `@Component` parameters: + + * `selector`: A CSS selector that tells Angular to create and insert an instance of this component + where it finds a `` tag in *parent* HTML. + For example, if an app's HTML contains ``, then + Angular inserts an instance of the `HeroListComponent` view between those tags. + + * `templateUrl`: The address of this component's template, which we showed [above](#the-template). + + * `directives`: An array of the components or directives that *this* template requires. + We saw in the last line of our template that we expect Angular to insert a `HeroDetailComponent` + in the space indicated by `` tags. + Angular will do so only if we mention the `HeroDetailComponent` in this `directives` array. + + * `providers`: An array of **dependency injection providers** for services that the component requires. + This is one way to tell Angular that our component's constructor requires a `HeroService` + so it can get the list of heroes to display. We'll get to dependency injection later. +figure + img(src="/resources/images/devguide/architecture/template-metadata-component.png" alt="Metadata" align="left" style="height:200px; margin-left:-40px;margin-right:10px" ) + +:marked + At runtime, Angular discovers the metadata specified by the `@Component` + annotation. That's how Angular learns how to do "the right thing". + + The template, metadata, and component together describe the view. + + We apply other metadata annotations in a similar fashion to guide Angular behavior. + `@Injectable`, `@Input`, `@Output`, and `@RouterConfig` are a few of the more popular annotations + we'll master as our Angular knowledge grows. +
+:marked + The architectural takeaway is that we must add metadata to our code + so that Angular knows what to do. + +.l-main-section + +:marked + ## Data binding + Without a framework, we would be responsible for pushing data values into the HTML controls and turning user responses + into actions and value updates. Writing such push/pull logic by hand is tedious, error-prone, and a nightmare to + read as any experienced jQuery programmer can attest. +figure + img(src="/resources/images/devguide/architecture/databinding.png" alt="Data Binding" style="width:220px; float:left; margin-left:-40px;margin-right:20px" ) +:marked + Angular supports **data binding**, + a mechanism for coordinating parts of a template with parts of a component. + We add binding markup to the template HTML to tell Angular how to connect both sides. + + There are four forms of data binding syntax. Each form has a direction — to the DOM, from the DOM, or in both directions — + as indicated by the arrows in the diagram. +
+:marked + We saw three forms of data binding in our [example](#template) template: ++makeExample('architecture/dart/lib/hero_list_component_1.html', 'binding')(format=".") +:marked + * The {‌{hero.name}} [interpolation](displaying-data.html#interpolation) + displays the component's `hero.name` property value within the `
` tags. + + * The `[hero]` property binding + passes the value of `selectedHero` from + the parent `HeroListComponent` to the `hero` property of the child `HeroDetailComponent`. + + * The `(click)` [event binding](user-input.html#click) calls the component's `selectHero` method when the user clicks a hero's name. + + **Two-way data binding** is an important fourth form + that combines property and event binding in a single notation, using the `ngModel` directive. + We didn't have a two-way binding in the `HeroListComponent` template; + here's an example from the `HeroDetailComponent` template: + ++makeExample('architecture/dart/lib/hero_detail_component.html', 'ng-model', 'lib/hero_detail_component.html (excerpt)')(format=".") +:marked + In two-way binding, a data property value flows to the input box from the component as with property binding. + The user's changes also flow back to the component, resetting the property to the latest value, + as with event binding. + + Angular processes *all* data bindings once per JavaScript event cycle, + depth-first from the root of the application component tree. + +figure + img(src="/resources/images/devguide/architecture/component-databinding.png" alt="Data Binding" style="float:left; width:300px; margin-left:-40px;margin-right:10px" ) +:marked + We don't know all the details yet, + but it's clear from these examples that data binding plays an important role in communication + between a template and its component. +
+figure + img(src="/resources/images/devguide/architecture/parent-child-binding.png" alt="Parent/Child binding" style="float:left; width:300px; margin-left:-40px;margin-right:10px" ) +:marked + Data binding is also important for communication between parent and child components. +
+ +.l-main-section + +:marked + ## Directives +figure + img(src="/resources/images/devguide/architecture/directive.png" alt="Parent child" style="float:left; width:150px; margin-left:-40px;margin-right:10px" ) +:marked + Angular templates are *dynamic*. When Angular renders them, it transforms the DOM + according to the instructions given by **directives**. + + A directive is a class with directive metadata. In Dart we apply the `@Directive` annotation + to attach metadata to the class. +
+:marked + We already met one form of directive: the component. A component is a *directive-with-a-template*; + a `@Component` annotation is actually a `@Directive` annotation extended with template-oriented features. + +.l-sub-section + :marked + While **a component is technically a directive**, + components are so distinctive and central to Angular applications that we chose + to separate components from directives in this architectural overview. +:marked + Two *other* kinds of directives exist: _structural_ and _attribute_ directives. + + They tend to appear within an element tag like attributes, + sometimes by name but more often as the target of an assignment or a binding. + + **Structural** directives alter layout by adding, removing, and replacing elements in DOM. + + Our [example](#template) template uses two built-in structural directives: ++makeExample('architecture/dart/lib/hero_list_component_1.html', 'structural')(format=".") +:marked + * [`*ngFor`](displaying-data.html#ng-for) tells Angular to stamp out one `
` per hero in the `heroes` list. + * [`*ngIf`](displaying-data.html#ng-if) includes the `HeroDetail` component only if a selected hero exists. + +.l-sub-section + :marked + In Dart, **the only value that is true is the boolean value `true`**; all + other values are false. JavaScript and TypeScript, in contrast, treat values + such as 1 and most non-null objects as true. For this reason, the JavaScript + and TypeScript versions of this app can use just `selectedHero` as the value + of the `*ngIf` expression. The Dart version must use a boolean operator such + as `!=` instead. + +:marked + **Attribute** directives alter the appearance or behavior of an existing element. + In templates they look like regular HTML attributes, hence the name. + + The `ngModel` directive, which implements two-way data binding, is + an example of an attribute directive. `ngModel` modifies the behavior of + an existing element (typically an ``) + by setting its display value property and responding to change events. + ++makeExample('architecture/dart/lib/hero_detail_component.html', 'ng-model')(format=".") +:marked + Angular ships with a small number of other directives that either alter the layout structure + (for example, `ngSwitch`) + or modify aspects of DOM elements and components + (for example, `ngStyle` and `ngClass`). + + + Of course, we can also write our own directives. Components such as + `HeroListComponent` are one kind of custom directive. + + +.l-main-section + +:marked + ## Services +figure + img(src="/resources/images/devguide/architecture/service.png" alt="Service" style="float:left; margin-left:-40px;margin-right:10px" ) +:marked + _Services_ is a broad category encompassing any value, function, or feature that our application needs. + + Almost anything can be a service. + A service is typically a class with a narrow, well-defined purpose. It should do something specific and do it well. +
+:marked + Examples include: + * logging service + * data service + * message bus + * tax calculator + * application configuration + + There is nothing specifically _Angular_ about services. Angular itself has no definition of a service. + There is no service base class, and no place to register a service. + + Yet services are fundamental to any Angular application. Our components are big consumers of services. + + We prefer our component classes lean. Our components don't fetch data from the server, + they don't validate user input, and they don't log directly to console. They delegate such tasks to services. + + A component's job is to enable the user experience and nothing more. It mediates between the view (rendered by the template) + and the application logic (which often includes some notion of a _model_). + A good component presents properties and methods for data binding. + It delegates everything nontrivial to services. + + Angular doesn't *enforce* these principles. + It won't complain if we write a "kitchen sink" component with 3000 lines. + + Angular does help us *follow* these principles by making it easy to factor our + application logic into services and make those services available to components through *dependency injection*. + +.l-main-section + +:marked + ## Dependency injection +figure + img(src="/resources/images/devguide/architecture/dependency-injection.png" alt="Service" style="float:left; width:200px; margin-left:-40px;margin-right:10px" ) +:marked + Dependency injection is a way to supply a new instance of a class + with the fully-formed dependencies it requires. Most dependencies are services. + Angular uses dependency injection to provide new components with the services they need. +
+:marked + Angular can tell which services a component needs by looking at the types of its constructor parameters. + For example, the constructor of our `HeroListComponent` needs a `HeroService`: ++makeExample('architecture/dart/lib/hero_list_component.dart', 'ctor', 'lib/hero_list_component.dart (excerpt)')(format='.') +:marked + When Angular creates a component, it first asks an **injector** for + the services that the component requires. + + An injector maintains a container of service instances that it has previously created. + If a requested service instance is not in the container, the injector makes one and adds it to the container + before returning the service to Angular. + When all requested services have been resolved and returned, + Angular can call the component's constructor with those services as arguments. + This is what we mean by *dependency injection*. + + The process of `HeroService` injection looks a bit like this: +figure + img(src="/resources/images/devguide/architecture/injector-injects.png" alt="Service" ) +:marked + If the injector doesn't have a `HeroService`, how does it know how to make one? + + In brief, we must have previously registered a **provider** of the `HeroService` with the injector. + A provider is something that can create or return a service, typically the service class itself. + + We can register providers at any level of the application component tree. + We often do so at the root when we bootstrap the application so that + the same instance of a service is available everywhere. ++makeExample('architecture/dart/web/main.dart', 'bootstrap', 'web/main.dart (excerpt)')(format='.') +:marked + Alternatively, we might register at a component level: ++makeExample('architecture/dart/lib/hero_list_component.dart', 'providers', 'lib/hero_list_component.dart (excerpt)')(format='.') +:marked + Registering at a component level means we get a new instance of the + service with each new instance of that component. + + + + Points to remember about dependency injection: + + * Dependency injection is wired into the Angular framework and used everywhere. + + * The *injector* is the main mechanism. + * An injector maintains a *container* of service instances that it created. + * An injector can create a new service instance from a *provider*. + + * A *provider* is a recipe for creating a service. + + * We register *providers* with injectors. + + +.l-main-section +:marked + ## Other stuff + + We've learned just a bit about the seven main building blocks of an Angular application: + 1. [Components](#component) + 1. [Templates](#template) + 1. [Metadata](#metadata) + 1. [Data binding](#data-binding) + 1. [Directives](#directive) + 1. [Services](#service) + 1. [Dependency injection](#dependency-injection) + + That's a foundation for everything else in an Angular application, + and it's more than enough to get going. + But it doesn't include everything we'll need or want to know. + + Here is a brief, alphabetical list of other important Angular features and services. + Most of them are covered in this Developers Guide (or soon will be). + + >**Animations:** A forthcoming animation library makes it easy for developers to animate component behavior + without deep knowledge of animation techniques or CSS. + + >**Bootstrap:** A method to configure and launch the root application component. + + >**Change detection:** Learn how Angular decides that a component property value has changed and + when to update the screen. + Learn how it uses **zones** to intercept asynchronous activity and run its change detection strategies. + + >**Component router:** With the component Router service, users can navigate a multi-screen application + in a familiar web browsing style using URLs. + + >**Events:** The DOM raises events. So can components and services. Angular offers mechanisms for + publishing and subscribing to events including an implementation of the [RxJS Observable](https://github.com/zenparsing/es-observable) proposal. + + >**[Forms](forms.html):** Support complex data entry scenarios with HTML-based validation and dirty checking. + + >**HTTP:** Communicate with a server to get data, save data, and invoke server-side actions with this Angular HTTP client. + + >**Lifecycle hooks:** We can tap into key moments in the lifetime of a component, from its creation to its destruction, + by implementing the lifecycle hook interfaces. + + >**Pipes:** Services that transform values for display. + We can put pipes in our templates to improve the user experience. Consider + this `currency` pipe expression: +
+code-example(language="javascript" linenumbers="."). + price | currency:'USD':true' +
+:marked + >It displays a price of "42.33" as `$42.33`. + + >**Testing:** Angular provides a + [testing library](https://pub.dartlang.org/packages/angular2_testing) + to run unit tests on our application parts as they interact with the Angular framework. diff --git a/public/docs/dart/latest/guide/displaying-data.jade b/public/docs/dart/latest/guide/displaying-data.jade index 661ddbfb89..60cdc5f5c0 100644 --- a/public/docs/dart/latest/guide/displaying-data.jade +++ b/public/docs/dart/latest/guide/displaying-data.jade @@ -60,6 +60,7 @@ All three of these files remain similar in the rest of the examples, so we'll focus on what changes. + .l-main-section h2#section-showing-properties-with-interpolation Showing properties with interpolation p. @@ -152,6 +153,7 @@ p Reload the app, and you'll now see the seconds updating automatically. + .l-main-section h2#Create-an-array Display an iterable using *ng-for p Moving up from a single value, create a property that's a list of values. @@ -268,6 +270,7 @@ code-example(language="dart"). @Component(selector: 'display', viewProviders: const [FriendsService]) + .l-main-section h2#Conditionally-displaying-data-with-NgIf Conditionally display data using *ng-if p. diff --git a/public/docs/dart/latest/guide/index.jade b/public/docs/dart/latest/guide/index.jade index cbcf5addb2..21027463c2 100644 --- a/public/docs/dart/latest/guide/index.jade +++ b/public/docs/dart/latest/guide/index.jade @@ -1,10 +1,93 @@ -- var number = 1; -ul.is-plain - for page, slug in public.docs[current.path[1]][current.path[2]].guide._data +include ../../../../_includes/_util-fns - if slug != '_listtype' && slug != 'index' - - var url = "/docs/" + current.path[1] + "/" + current.path[2] + "/" + current.path[3] + "/" + slug + ".html" - - var num = number++ +:marked + This Developers Guide is a practical guide to Angular for experienced programmers who + are building client applications in HTML and Dart. +figure + img(src="/resources/images/devguide/intro/people.png" alt="Us" align="left" style="width:200px; margin-left:-40px;margin-right:10px" ) +:marked + We are on a journey together to understand how Angular works and, more importantly, + how to make it work for us. We look at our application requirements and we see problems to solve. +
- li - != partial("../../../../_includes/_hover-card", { icon: "icon-number", number: num, name: page.title, url: url }) + * How do we get data onto the screen and handle user interactions? + * How do we organize our code into manageable, cohesive chunks of functionality that work together? + * What are the essential Angular building blocks and how do they help? + * How do we minimize routine, mechanical coding in favor of declarative, higher level constructs without losing control? + + This chapter begins the journey. + + +:marked + # How to read this guide + Each chapter of this guide targets an Angular feature, + showing how to use it to solve a programming problem. + + All the chapters include code snippets ... snippets we can reuse in our own applications. + Typically, these snippets are excerpts from a sample application that accompanies the chapter. + + **All the source files** for each sample app are displayed together at the **end of each chapter.** + + + + + + + + Here is a learning path we might follow: + + 1. First, be familiar with Dart programming and with web concepts such as + the DOM, HTML, and CSS. Dart tutorials such as + [Get Started](https://www.dartlang.org/docs/tutorials/get-started/) and + [Connect Dart & HTML](https://www.dartlang.org/docs/tutorials/connect-dart-html/) + are a great way to start. + + 1. Follow the [QuickStart](../quickstart), which is the "Hello, World" of Angular 2. + It shows how to set up the libraries and tools needed to write *any* Angular app. + It ends with a "proof of life", a running Angular app. + + 1. Next, read the Developers Guide chapters in order: + + 1. The rest of this chapter, especially the Architecture overview + 1. [Displaying Data](displaying-data.html) + 1. [User Input](user-input.html) + 1. [Forms](forms.html) + + + + 1. Consider hopping over to the [TypeScript docs](/docs/ts/latest/) + since they're currently ahead of the Dart docs. (We're working on that!) + Especially check out the [Tutorial](/docs/ts/latest/tutorial/) and + [Cheat Sheet](/docs/ts/latest/guide/cheatsheet.html), and the guide chapters + [Dependency Injection](/docs/ts/latest/guide/dependency-injection.html) + and [Template Syntax](/docs/ts/latest/guide/template-syntax.html). + + + + Don't miss the [Cheat Sheet](cheatsheet.html), a handy map to Angular. + + +.l-main-section +:marked + # Appendix: The Hero Staffing Agency + + There's a backstory to the samples in this guide. + + The world is full of crises large and small. + Fortunately, courageous heroes are prepared to take on every challenge. + The shadowy Hero Staffing Agency matches crises to heroes. + + We are contract developers, hired by the Agency to build an application to manage their operations. + The Agency maintains a stable of heroes with special powers. + Ordinary humans submit crises as job requests. The heroes bid to take the job, and the Agency + assigns each job accordingly. + + Our application handles every detail of recruiting, tracking, and job assignment. + For example, the [Forms](forms.html) chapter features a screen for + entering personal information about heroes: + +figure.image-display + img(src="/resources/images/devguide/forms/hero-form-1.png" width="400px" alt="Clean Form") diff --git a/public/docs/dart/latest/guide/setup.jade b/public/docs/dart/latest/guide/setup.jade deleted file mode 100644 index 52dd73292f..0000000000 --- a/public/docs/dart/latest/guide/setup.jade +++ /dev/null @@ -1,168 +0,0 @@ -.l-main-section - - p. - As long as you already - have the Dart SDK, - getting started with Angular 2 is simple: - - ol - li Depend on the angular2 pub package. - li Create a Dart file that defines (directly or indirectly) a - root component and bootstraps Angular. - li Create an HTML file that uses the root component and points to the Dart file - - p. - You can use whichever editor or IDE you like, - or just use the command-line tools that the Dart SDK provides. - See Dart Tools - for more information. - - - h2#section-install Depend on angular2 - - p. - To use Angular2 in your app, include angular2 as a dependency in - your app's pubspec.yaml file. For example: - - code-example(language="yaml"). - # pubspec.yaml - name: getting_started - description: Getting Started example - version: 0.0.1 - dependencies: - angular2: 2.0.0-alpha.45 - browser: ^0.10.0 - transformers: - - angular2: - entry_points: web/main.dart - p. - Run pub get to download the packages your app depends on. - (Dart-savvy editors and IDEs - typically run pub get for you.) - - -.l-main-section - h2#section-set-up-the-starting-component Write the Dart code - - p. - Next to your pubspec.yaml file, - create a web subdirectory containing a Dart file - (main.dart). - Edit main.dart, adding a component class (AppComponent), - configuring it to bind to the <my-app> element, - and creating a top-level main() function that calls - Angular's bootstrap() function. - - code-example(language="dart" escape="html"). - // web/main.dart - import 'package:angular2/angular2.dart'; - import 'package:angular2/bootstrap.dart'; - - @Component(selector: 'my-app') - @View(template: '

My first Angular 2 App

') - class AppComponent {} - - main() { - bootstrap(AppComponent); - } - -.l-main-section - h2#section-create-an-entry-point Create an HTML file - p. - In the web/ directory of your app, - create an HTML file (index.html). - Edit index.html to add a <my-app> element - and call main.dart. - - code-example(language="html"). - <!-- web/index.html --> - <!DOCTYPE html> - <html> - <head> - <title>Getting Started</title> - <link rel="stylesheet" href="style.css"> - <script async src="main.dart" type="application/dart"></script> - <script async src="packages/browser/dart.js"></script> - </head> - <body> - <my-app></my-app> - </body> - </html> - -.l-main-section - h2#section-run-it Run the app! - - p. - Now run the app. How you do this depends on your tools. - - ul - li. - If you're using WebStorm or IntelliJ IDEA, - right-click web/index.html, - and choose Run 'index.html'. - - li. - If you're using the command line and don't have Dartium, - serve the app using pub serve, - and then run it by visiting http://localhost:8080 in a browser. - Generating the JavaScript takes a few seconds when you first visit the page, - and the generated JavaScript is currently large. - The generated JavaScript will be smaller once - Angular's transformer becomes available. - - p. - You should see something like this: - - figure.image-display - img(src='/resources/images/examples/setup-example1.png' alt="Example of Todo App") - -.l-main-section - h2#section-explanations Explanations - - p This basic Angular app contains the structure for any app you'll build. - - .l-sub-section - h3 It's all a tree - - p. - You can think of an Angular app as a tree of components. - The root component acts as the top-level container for the rest of your application. - You've named this one AppComponent, but there's - nothing special about the name; you can use whatever makes sense to you. - - p. - The root component's job is to give a location in the HTML file where - your application can - render through its element—in this case, <my-app>. - There's nothing special about the HTML filename or the element name; - you can pick whatever you like. - - p. - The root component loads the initial template for the application, - which loads other components to perform - whatever functions your application needs—menu bars, views, forms, and so on. - We'll walk through examples of all of - these in the following pages. - - .l-sub-section - h3 @Component and @View annotations - - p. - A component annotation describes details about the component. - An annotation can be identified by its at-sign (@). - p. - The @Component annotation defines the HTML tag for - the component by specifying the component's CSS selector. - p. - The @View annotation defines the HTML that - represents the component. - The component you wrote uses an inline template, - but you can also have an external template. - To use an external template, - specify a templateUrl property and - give it the path to the HTML file. - - - p. - Exciting! Not excited yet? - Let's move on to Displaying Data. diff --git a/public/docs/dart/latest/guide/user-input.jade b/public/docs/dart/latest/guide/user-input.jade index 54d774f6f6..9ce55e0f3c 100644 --- a/public/docs/dart/latest/guide/user-input.jade +++ b/public/docs/dart/latest/guide/user-input.jade @@ -81,6 +81,7 @@ </li> </ul> + .l-main-section h2#section-add-todos-to-the-list Add todos to the list via button click p.