docs(devguide): first chapter dart examples and a typo
This commit is contained in:
parent
d3f8fb741a
commit
21031a6d2e
|
@ -0,0 +1,35 @@
|
||||||
|
{
|
||||||
|
"_listtype": "ordered",
|
||||||
|
|
||||||
|
"setup": {
|
||||||
|
"title": "Getting Started"
|
||||||
|
},
|
||||||
|
|
||||||
|
"displaying-data": {
|
||||||
|
"title": "Displaying Data"
|
||||||
|
},
|
||||||
|
|
||||||
|
"user-input": {
|
||||||
|
"title": "User Input"
|
||||||
|
},
|
||||||
|
|
||||||
|
"making-components": {
|
||||||
|
"title": "Making Components"
|
||||||
|
},
|
||||||
|
|
||||||
|
"talking-to-components": {
|
||||||
|
"title": "Talking to Components"
|
||||||
|
},
|
||||||
|
|
||||||
|
"using-forms": {
|
||||||
|
"title": "Using Forms"
|
||||||
|
},
|
||||||
|
|
||||||
|
"transforming-data": {
|
||||||
|
"title": "Transforming data (pipes)"
|
||||||
|
},
|
||||||
|
|
||||||
|
"reusing-components": {
|
||||||
|
"title": "Reusing Components"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
doctype
|
||||||
|
html(lang="en" ng-app="angularIOApp")
|
||||||
|
head
|
||||||
|
!= partial("../../../../_includes/_head-include")
|
||||||
|
|
||||||
|
body(class="l-offset-nav l-offset-side-nav" ng-controller="AppCtrl")
|
||||||
|
!= partial("../../../../_includes/_main-nav")
|
||||||
|
!= partial("../../../../_includes/_docs-nav")
|
||||||
|
!= partial("../../../../_includes/_hero")
|
||||||
|
|
||||||
|
if banner
|
||||||
|
!= partial("../../../../_includes/_banner")
|
||||||
|
|
||||||
|
article.l-content-small.grid-fluid.docs-content(ng-non-bindable)
|
||||||
|
!= yield
|
||||||
|
!= partial("../../../../_includes/_next-item")
|
||||||
|
|
||||||
|
!= partial("../../../../_includes/_footer")
|
||||||
|
!= partial("../../../../_includes/_scripts-include")
|
|
@ -0,0 +1,334 @@
|
||||||
|
.l-main-section
|
||||||
|
p.
|
||||||
|
Displaying data is job number one for any good application. In Angular, you bind data to elements in HTML
|
||||||
|
templates and Angular automatically updates the UI as data changes.
|
||||||
|
p.
|
||||||
|
Let's walk through how we'd display a property, a list of properties, and then conditionally show content
|
||||||
|
based on state.
|
||||||
|
p.
|
||||||
|
We'll end up with a UI that looks like this:
|
||||||
|
div(align='center')
|
||||||
|
img(src='displaying-data-example1.png')
|
||||||
|
|
||||||
|
.l-main-section
|
||||||
|
h2#section-create-an-entry-point Create an entry point
|
||||||
|
|
||||||
|
p Open your favorite editor and create a show-properties.html file with the content:
|
||||||
|
pre.prettyprint.linenums.lang-html
|
||||||
|
code.
|
||||||
|
//ES5
|
||||||
|
<display></display>
|
||||||
|
|
||||||
|
pre.prettyprint.linenums.lang-html
|
||||||
|
code.
|
||||||
|
//TypeScript
|
||||||
|
<display></display>
|
||||||
|
|
||||||
|
p
|
||||||
|
| The <code><display></code> component here acts as the site where you'll insert your application.
|
||||||
|
| We'll assume a structure like this for the rest of the examples here and just focus on the parts that
|
||||||
|
| are different.
|
||||||
|
|
||||||
|
.l-main-section
|
||||||
|
h2#section-showing-properties-with-interpolation Showing properties with interpolation
|
||||||
|
p.text-body
|
||||||
|
| The simple method for binding text into templates is through interpolation where you put the name of a property
|
||||||
|
| inside <strong>{{ }}</strong>.
|
||||||
|
|
||||||
|
p To see this working, create another file, <code>show-properties.js</code>, and add the following:
|
||||||
|
|
||||||
|
pre.prettyprint.linenums.lang-javascript
|
||||||
|
code.
|
||||||
|
// ES5
|
||||||
|
function DisplayComponent() {
|
||||||
|
this.myName = "Alice";
|
||||||
|
}
|
||||||
|
DisplayComponent.annotations = [
|
||||||
|
new angular.Component({
|
||||||
|
selector: "display"
|
||||||
|
}),
|
||||||
|
new angular.View({
|
||||||
|
template:
|
||||||
|
'<p>My name: {{ myName }}</p>',
|
||||||
|
directives: [angular.For, angular.If]
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
pre.prettyprint.linenums.lang-typescript
|
||||||
|
code.
|
||||||
|
// TypeScript
|
||||||
|
import {Component, View, bootstrap, For} from 'angular2/angular2';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'display'
|
||||||
|
})
|
||||||
|
@View({
|
||||||
|
template: `
|
||||||
|
<p>My name: {{ myName }}</p>
|
||||||
|
`,
|
||||||
|
directives: [For]
|
||||||
|
})
|
||||||
|
class DisplayComponent {
|
||||||
|
myName: string;
|
||||||
|
todos: Array<string>;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.myName = "Alice";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.
|
||||||
|
You've just defined a component that encompases a view and controller for the app. The view
|
||||||
|
defines a template:
|
||||||
|
pre.prettyprint.lang-html
|
||||||
|
code.
|
||||||
|
<p>My name: {{ myName }}</p>
|
||||||
|
|
||||||
|
p.
|
||||||
|
Angular will automatically pull the value of <code>myName</code> and insert it into the browser and
|
||||||
|
update it whenever it changes without work on your part.
|
||||||
|
|
||||||
|
p.
|
||||||
|
One thing to notice here is that though you've written your <code>DisplayComponent</code> class, you haven't
|
||||||
|
called new to create one anywhere. By associating your class with elements named 'display' in
|
||||||
|
the DOM, Angular knows to automatically call new on <code>DisplayComponent</code> and bind its properties to
|
||||||
|
that part of the template.
|
||||||
|
|
||||||
|
p.
|
||||||
|
When you're building templates, data bindings like these have access to the same scope of
|
||||||
|
properties as your controller class does. Here, your class is the <code>DisplayComponent</code> that has
|
||||||
|
just one property, myName.
|
||||||
|
|
||||||
|
.callout.is-helpful
|
||||||
|
header Note
|
||||||
|
p.
|
||||||
|
While you've used <code>template:</code> to specify an inline view, for larger templates you'd
|
||||||
|
want to move them to a separate file and load them with <code>templateUrl:</code> instead.
|
||||||
|
|
||||||
|
p So you can see Angular dynamically update content, add a line after
|
||||||
|
|
||||||
|
pre.prettyprint.lang-html
|
||||||
|
code.
|
||||||
|
<p>My name: {{ myName }}</p>
|
||||||
|
p to this:
|
||||||
|
pre.prettyprint.lang-html
|
||||||
|
code.
|
||||||
|
<p>Current time: {{ time }}</p>
|
||||||
|
p.
|
||||||
|
Then give the <code>DisplayComponent</code> a starting value for time and a call to update time
|
||||||
|
via <code>setInterval</code>.
|
||||||
|
|
||||||
|
pre.prettyprint.lang-javascript
|
||||||
|
code.
|
||||||
|
setInterval(function () { this.time = (new Date()).toString(); }.bind(this), 1000);
|
||||||
|
p Reload the page in your browser and you'll now see the seconds updating automatically.
|
||||||
|
.l-main-section
|
||||||
|
h2#Create-an-array Create an array property and use For on the view
|
||||||
|
p Moving up from a single property, create an array to display as a list.
|
||||||
|
pre.prettyprint.lang-javascript
|
||||||
|
code.
|
||||||
|
//ES5
|
||||||
|
function DisplayComponent() {
|
||||||
|
this.myName = "Alice";
|
||||||
|
this.names = ["Aarav", "Martín", "Shannon", "Ariana", "Kai"];
|
||||||
|
}
|
||||||
|
pre.prettyprint.lang-typescript
|
||||||
|
code.
|
||||||
|
//Typescript
|
||||||
|
constructor() {
|
||||||
|
this.myName = "Alice";
|
||||||
|
this.names = ["Aarav", "Martín", "Shannon", "Ariana", "Kai"];
|
||||||
|
}
|
||||||
|
p.
|
||||||
|
You can then use this array in your template with the <code>for</code> directive to create copies of DOM elements
|
||||||
|
with one for each item in the array.
|
||||||
|
pre.prettyprint.lang-javascript
|
||||||
|
code.
|
||||||
|
//ES5
|
||||||
|
template:
|
||||||
|
'<p>My name: {{ myName }}</p>' +
|
||||||
|
'<p>Friends:</p>' +
|
||||||
|
'<ul>' +
|
||||||
|
'<li *for="#name of names">' +
|
||||||
|
'{{ name }}' +
|
||||||
|
'</li>' +
|
||||||
|
'</ul>',
|
||||||
|
|
||||||
|
pre.prettyprint.lang-typescript
|
||||||
|
code.
|
||||||
|
//Typescript
|
||||||
|
template: `
|
||||||
|
<p>My name: {{ myName }}</p>
|
||||||
|
<p>Friends:</p>
|
||||||
|
<ul>
|
||||||
|
<li *for="#name of names">
|
||||||
|
{{ name }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
`,
|
||||||
|
p.
|
||||||
|
To make this work, you'll also need to add the <code>angular.For</code> directive used by the template so
|
||||||
|
that Angular knows to include it:
|
||||||
|
|
||||||
|
pre.prettyprint.lang-javascript
|
||||||
|
code.
|
||||||
|
//ES5
|
||||||
|
directives: [angular.For]
|
||||||
|
pre.prettyprint.lang-typescript
|
||||||
|
code.
|
||||||
|
//Typescript
|
||||||
|
import {Component, View, bootstrap, For} from
|
||||||
|
...
|
||||||
|
directives: [For]
|
||||||
|
p Reload and you've got your list of friends!
|
||||||
|
p.
|
||||||
|
Again, Angular will mirror changes you make to this list over in the DOM. Add a new item and it appears in your
|
||||||
|
list. Delete one and Angular deletes the <li>. Reorder items and Angular makes the corresponding reorder of
|
||||||
|
the DOM list.
|
||||||
|
p Let's look at the few lines that do the work again:
|
||||||
|
pre.prettyprint.lang-html
|
||||||
|
code.
|
||||||
|
//HTML
|
||||||
|
<li *for="#name of names">
|
||||||
|
{{ name }}
|
||||||
|
</li>
|
||||||
|
p The way to read this is:
|
||||||
|
ul
|
||||||
|
li.
|
||||||
|
<code>*for</code> : create a DOM element for each item in an
|
||||||
|
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols">iterable</a>
|
||||||
|
like an array
|
||||||
|
li <code>#name</code> : refer to individual values of the iterable as 'name'
|
||||||
|
li <code>of names</code> : the iterable to use is called 'names' in the current controller
|
||||||
|
p Using this syntax, you can build UI lists from any iterable object.
|
||||||
|
.l-main-section
|
||||||
|
h2#Create-a-class Create a class for the array property and inject into component
|
||||||
|
p.
|
||||||
|
Before we get too much further, we should mention that putting our model (array) directly in our controller isn't
|
||||||
|
proper form. We should separate the concerns by having another class serve the role of model and inject it into
|
||||||
|
the controller.
|
||||||
|
p Make a <code>FriendsService</code> class to provide the model with the list of friends.
|
||||||
|
pre.prettyprint.lang-javascript
|
||||||
|
code.
|
||||||
|
function FriendsService() {
|
||||||
|
this.names = ["Alice", "Aarav", "Martín", "Shannon", "Ariana", "Kai"];
|
||||||
|
}
|
||||||
|
p.
|
||||||
|
Replace the current list of friends in DisplayComponent by passing in the FriendsService and setting the list of
|
||||||
|
names in DisplayComponent to the names provided by the service you passed in.
|
||||||
|
pre.prettyprint.lang-javascript
|
||||||
|
code.
|
||||||
|
function DisplayComponent(friends) {
|
||||||
|
this.myName = "Alice";
|
||||||
|
this.names = friends.names;
|
||||||
|
}
|
||||||
|
p And then make FriendsService available to dependency injection
|
||||||
|
pre.prettyprint.lang-javascript
|
||||||
|
code.
|
||||||
|
DisplayComponent.annotations = [
|
||||||
|
new angular.Component({
|
||||||
|
selector: "display",
|
||||||
|
injectables: [FriendsService]
|
||||||
|
}),
|
||||||
|
...
|
||||||
|
DisplayComponent.parameters = [[FriendsService]];
|
||||||
|
.callout.is-helpful
|
||||||
|
header ES5 Note
|
||||||
|
p.
|
||||||
|
The dependency injection syntax here is using the low-level API and is...well...not very nice. We're
|
||||||
|
working on sugaring the syntax to match the way it works in Angular 1. Expect this to change soon.
|
||||||
|
pre.prettyprint.lang-javascript
|
||||||
|
code.
|
||||||
|
//ES5
|
||||||
|
function FriendsService() {
|
||||||
|
this.names = ["Alice", "Aarav", "Martín", "Shannon", "Ariana", "Kai"];
|
||||||
|
}
|
||||||
|
function DisplayComponent(friends) {
|
||||||
|
this.myName = "Alice";
|
||||||
|
this.names = friends.names;
|
||||||
|
}
|
||||||
|
DisplayComponent.annotations = [
|
||||||
|
new angular.Component({
|
||||||
|
selector: "display",
|
||||||
|
injectables: [FriendsService]
|
||||||
|
}),
|
||||||
|
new angular.View({
|
||||||
|
template: '{{ myName }} <ul> <li *for="#name of names"<{{ name }}>/li< >/ul<',
|
||||||
|
directives: [angular.For, angular.If]
|
||||||
|
})
|
||||||
|
];
|
||||||
|
DisplayComponent.parameters = [[FriendsService]];
|
||||||
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
|
angular.bootstrap(DisplayComponent);
|
||||||
|
});
|
||||||
|
pre.prettyprint.lang-typescript
|
||||||
|
code.
|
||||||
|
//TypeScript
|
||||||
|
import {Component, View, bootstrap, For} from
|
||||||
|
...
|
||||||
|
directives: [For]
|
||||||
|
.l-main-section
|
||||||
|
h2#Conditionally-displaying-data-with-If Conditionally displaying data with If
|
||||||
|
p.
|
||||||
|
Lastly, before we move on, let's handle showing parts of our UI conditionally with <code>If</code>. The
|
||||||
|
<code>If</code> directive adds or removes elements from the DOM based on the expression you provide.
|
||||||
|
p See it in action by adding a paragraph at the end of your template
|
||||||
|
pre.prettyprint.lang-html
|
||||||
|
code.
|
||||||
|
<p *if="names.length > 3">You have many friends!</p>
|
||||||
|
p You'll also need to add the If directive so Angular knows to include it.
|
||||||
|
p [TODO: CODE]
|
||||||
|
p.
|
||||||
|
As there are currently 5 items it the list, you'll see the message congratulating you on your many friends.
|
||||||
|
Remove two items from the list, reload your browser, and see that the message no longer displays.
|
||||||
|
pre.prettyprint.lang-javascript
|
||||||
|
code.
|
||||||
|
//ES5
|
||||||
|
function DisplayComponent() {
|
||||||
|
this.myName = "Alice";
|
||||||
|
this.names = ["Aarav", "Martín", "Shannon", "Ariana", "Kai"];
|
||||||
|
}
|
||||||
|
DisplayComponent.annotations = [
|
||||||
|
new angular.Component({
|
||||||
|
selector: "display"
|
||||||
|
}),
|
||||||
|
new angular.View({
|
||||||
|
template:
|
||||||
|
'<p>My name: {{ myName }}</p>' +
|
||||||
|
'<p>Friends:</p>' +
|
||||||
|
'<ul>' +
|
||||||
|
'<li *for="#name of names">' +
|
||||||
|
'{{ name }}' +
|
||||||
|
'</li>' +
|
||||||
|
'</ul>' +
|
||||||
|
'<p *if="names.length > 3">You have many friends!</p>',
|
||||||
|
directives: [angular.For, angular.If]
|
||||||
|
})
|
||||||
|
];
|
||||||
|
pre.prettyprint.lang-typescript
|
||||||
|
code.
|
||||||
|
//TypeScript
|
||||||
|
import {Component, View, bootstrap, For, If} from 'angular2/angular2';
|
||||||
|
@Component({
|
||||||
|
selector: 'display'
|
||||||
|
})
|
||||||
|
@View({
|
||||||
|
template: `
|
||||||
|
<p>My name: {{ myName }}</p>
|
||||||
|
<p>Friends:</p>
|
||||||
|
<ul>
|
||||||
|
<li *for="#name of names">
|
||||||
|
{{ name }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p *if="names.length > 3">You have many friends!</p>
|
||||||
|
`,
|
||||||
|
directives: [For, If]
|
||||||
|
})
|
||||||
|
class DisplayComponent {
|
||||||
|
myName: string;
|
||||||
|
todos: Array<string>;
|
||||||
|
constructor() {
|
||||||
|
this.myName = "Alice";
|
||||||
|
this.names = ["Aarav", "Martín", "Shannon", "Ariana", "Kai"];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
.l-main-section
|
||||||
|
h2#section-install-or-plunker Install Angular or Use Plunker
|
||||||
|
p There are five steps to create any Angular app:
|
||||||
|
ol
|
||||||
|
li Create an entry point HTML file where users will start
|
||||||
|
li Load the Angular library at the top of the file
|
||||||
|
li Make a root component for your application
|
||||||
|
li Bootstrap Angular
|
||||||
|
|
||||||
|
p.
|
||||||
|
Dart makes dependencies available to the application through the <code>pubspec.yaml</code> file.
|
||||||
|
To use Angular2 in your app, include angular as a dependency. Here’s the minimal
|
||||||
|
<code>pubspec.yaml</code> file for this sample:
|
||||||
|
|
||||||
|
pre.prettyprint.lang-dart
|
||||||
|
code.
|
||||||
|
name: getting_started
|
||||||
|
description: Dart version of Angular 2 example, Getting Started
|
||||||
|
version: 0.0.1
|
||||||
|
dependencies:
|
||||||
|
angular2: 2.0.0-alpha.20
|
||||||
|
browser: any
|
||||||
|
|
||||||
|
|
||||||
|
p.
|
||||||
|
The Dart Editor automatically downloads the packages your app depends on, along with any packages that they, in
|
||||||
|
turn, depend on. If this download fails or you like using the command line, you can explicitly install packages.
|
||||||
|
From Dart Editor, you can use <strong>Tools > Pub Get</strong>. From the command line (in the root directory of
|
||||||
|
your app, assuming the Dart SDK is in your path), you can run <code>pub get</code>.
|
||||||
|
|
||||||
|
.l-main-section
|
||||||
|
h2#section-create-an-entry-point Create an entry point
|
||||||
|
p.
|
||||||
|
Create an <code>index.html</code> file and add the Angular library tags and a <code>main.js</code> file where
|
||||||
|
you'll build your first component.
|
||||||
|
|
||||||
|
p.
|
||||||
|
In the <code><body></code>, add an element called <code><my-app></code> that will be the root of your
|
||||||
|
application.
|
||||||
|
|
||||||
|
pre.prettyprint.lang-html
|
||||||
|
code.
|
||||||
|
//index.html
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<my-app></my-app>
|
||||||
|
<script type="application/dart" src="main.dart"></script>
|
||||||
|
<script src="packages/browser/dart.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
||||||
|
.l-main-section
|
||||||
|
h2#section-set-up-the-starting-component Set up the starting component
|
||||||
|
|
||||||
|
p.
|
||||||
|
In <code>main.dart</code>, create a class called <code>AppComponent</code>, configure it to bind to the
|
||||||
|
<code><my-app></code> element in <code>index.html</code>, and call Angular's <code>bootstrap()</code> to kick
|
||||||
|
it all off like this:
|
||||||
|
|
||||||
|
pre.prettyprint.lang-dart
|
||||||
|
code.
|
||||||
|
//main.dart
|
||||||
|
import 'package:angular2/angular2.dart';
|
||||||
|
import 'package:angular2/src/reflection/reflection.dart' show reflector;
|
||||||
|
import 'package:angular2/src/reflection/reflection_capabilities.dart' show ReflectionCapabilities;
|
||||||
|
|
||||||
|
@Component(
|
||||||
|
selector: 'my-app'
|
||||||
|
)
|
||||||
|
@View(
|
||||||
|
template: '<h1>My first Angular 2 App</h1>'
|
||||||
|
)
|
||||||
|
class AppComponent {
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
reflector.reflectionCapabilities = new ReflectionCapabilities();
|
||||||
|
bootstrap(AppComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.l-main-section
|
||||||
|
h2#section-run-it Run it!
|
||||||
|
|
||||||
|
p.
|
||||||
|
Now run the app. In Dart Editor’s Files view, select <code>index.html</code>, right-click, and choose <strong>Run
|
||||||
|
in Dartium</strong>.
|
||||||
|
|
||||||
|
You should see:
|
||||||
|
div(align='center')
|
||||||
|
img(src='setup-example1.png')
|
||||||
|
|
||||||
|
.l-main-section
|
||||||
|
h2#section-explanations Explanations
|
||||||
|
|
||||||
|
p This basic Angular app contains the structure for any app you'll build.
|
||||||
|
|
||||||
|
p.
|
||||||
|
You can think of Angular apps as a tree of components. This root component we've been talking about acts as the top
|
||||||
|
level container for the rest of your application. You've named this one <code>AppComponent</code>, but there's
|
||||||
|
nothing special about the name and you can use whatever makes sense to you.
|
||||||
|
|
||||||
|
p.
|
||||||
|
The root component's job is to give a location in the <code>index.html</code> file where your application will
|
||||||
|
render through it's element, in this case <code><my-app></code>. There is also nothing special about this
|
||||||
|
element name and you can pick it as you like.
|
||||||
|
|
||||||
|
p.
|
||||||
|
The root component loads the initial template for the application that will load other components to perform
|
||||||
|
whatever functions your application needs - menu bars, views, forms, etc. We'll walk through examples of all of
|
||||||
|
these in the following pages.
|
||||||
|
|
||||||
|
p Exciting! Not excited yet? Let's move on to <a href="displaying-data.html">Displaying Data</a>.
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
"transforming-data": {
|
"transforming-data": {
|
||||||
"title": "Tranforming data (pipes)"
|
"title": "Transforming data (pipes)"
|
||||||
},
|
},
|
||||||
|
|
||||||
"reusing-components": {
|
"reusing-components": {
|
||||||
|
|
Loading…
Reference in New Issue