2015-04-18 16:56:30 -04:00
|
|
|
.l-main-section
|
2015-04-19 17:35:53 -04:00
|
|
|
|
2015-04-22 08:42:47 -04:00
|
|
|
h2#section-displaying-controller-properties Displaying controller properties
|
|
|
|
|
2015-04-22 10:17:26 -04:00
|
|
|
|
2015-04-22 08:25:15 -04:00
|
|
|
p.
|
2015-04-22 10:17:26 -04:00
|
|
|
Let's walk through how we'd display a property, a list of properties, and then conditionally show content
|
|
|
|
based on state. We'll end up with a UI that looks like this:
|
|
|
|
|
|
|
|
figure.image-display
|
|
|
|
img(src='displaying-data-example1.png')
|
2015-04-18 16:56:30 -04:00
|
|
|
|
2015-05-05 01:14:09 -04:00
|
|
|
.callout.is-helpful
|
|
|
|
header Typescript vs ES5
|
|
|
|
p.
|
|
|
|
Although we work through the examples in TypeScript, you can also use
|
|
|
|
regular ES5. Click the ES5 link in any code box to see the ES5 JavaScript
|
|
|
|
version. Note that in ES5, you'd want to name your files <code>.js</code> rather than
|
|
|
|
<code>.ts</code>.
|
|
|
|
|
2015-04-18 16:56:30 -04:00
|
|
|
.l-main-section
|
|
|
|
h2#section-create-an-entry-point Create an entry point
|
2015-04-19 13:24:28 -04:00
|
|
|
|
2015-04-18 16:56:30 -04:00
|
|
|
p Open your favorite editor and create a show-properties.html file with the content:
|
2015-05-05 12:56:18 -04:00
|
|
|
|
|
|
|
code-example(language="html" escape="html").
|
|
|
|
<display></display>
|
|
|
|
|
2015-04-18 16:56:30 -04:00
|
|
|
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
|
2015-04-19 18:21:21 -04:00
|
|
|
p.text-body
|
2015-04-18 16:56:30 -04:00
|
|
|
| The simple method for binding text into templates is through interpolation where you put the name of a property
|
|
|
|
| inside <strong>{{ }}</strong>.
|
|
|
|
|
2015-05-05 01:14:09 -04:00
|
|
|
p To see this working, create another file, <code>show-properties.ts</code>, and add the following:
|
2015-04-19 13:24:28 -04:00
|
|
|
|
2015-05-05 12:56:18 -04:00
|
|
|
code-tabs
|
2015-05-19 15:32:55 -04:00
|
|
|
code-pane(language="javascript" name="TypeScript" format="linenums").
|
2015-05-05 12:56:18 -04:00
|
|
|
// TypeScript
|
2015-05-19 15:21:59 -04:00
|
|
|
import {Component, View, bootstrap} from 'angular2/angular2';
|
2015-05-05 12:56:18 -04:00
|
|
|
|
|
|
|
@Component({
|
|
|
|
selector: 'display'
|
|
|
|
})
|
|
|
|
@View({
|
2015-05-19 09:33:09 -04:00
|
|
|
template: `
|
2015-05-19 15:32:55 -04:00
|
|
|
<p>My name: {{ myName }}</p>
|
2015-05-19 15:21:59 -04:00
|
|
|
`
|
2015-05-05 12:56:18 -04:00
|
|
|
})
|
|
|
|
class DisplayComponent {
|
|
|
|
myName: string;
|
|
|
|
|
|
|
|
constructor() {
|
|
|
|
this.myName = "Alice";
|
|
|
|
}
|
|
|
|
}
|
2015-05-19 15:32:55 -04:00
|
|
|
code-pane(language="javascript" name="ES5" format="linenums").
|
2015-05-19 09:33:09 -04:00
|
|
|
// ES5
|
|
|
|
function DisplayComponent() {
|
|
|
|
this.myName = "Alice";
|
|
|
|
}
|
|
|
|
DisplayComponent.annotations = [
|
|
|
|
new angular.ComponentAnnotation({
|
|
|
|
selector: "display"
|
|
|
|
}),
|
|
|
|
new angular.ViewAnnotation({
|
|
|
|
template:
|
2015-05-19 15:21:59 -04:00
|
|
|
'<p>My name: {{ myName }}</p>'
|
2015-05-19 09:33:09 -04:00
|
|
|
})
|
|
|
|
];
|
|
|
|
|
|
|
|
|
2015-04-19 13:24:28 -04:00
|
|
|
p.
|
2015-05-02 19:51:25 -04:00
|
|
|
You've just defined a component that encompasses a view and controller for the app. The view
|
2015-04-19 13:24:28 -04:00
|
|
|
defines a template:
|
2015-05-05 12:56:18 -04:00
|
|
|
|
|
|
|
code-example(language="html" escape="html").
|
|
|
|
<p>My name: {{ myName }}</p>
|
2015-04-19 13:24:28 -04:00
|
|
|
|
|
|
|
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
|
2015-05-05 12:56:18 -04:00
|
|
|
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.
|
2015-04-19 13:24:28 -04:00
|
|
|
|
|
|
|
.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.
|
2015-05-05 12:56:18 -04:00
|
|
|
|
|
|
|
code-tabs
|
2015-05-19 17:31:43 -04:00
|
|
|
code-pane(language="javascript" name="TypeScript" format="linenums").
|
2015-05-05 12:56:18 -04:00
|
|
|
//Typescript
|
2015-05-19 17:33:21 -04:00
|
|
|
class DisplayComponent {
|
|
|
|
myName: string;
|
|
|
|
<span class='otl'>names: Array<string>;</span>
|
|
|
|
|
|
|
|
constructor() {
|
|
|
|
this.myName = "Alice";
|
|
|
|
<span class='otl'>this.names = ["Aarav", "Martín", "Shannon", "Ariana", "Kai"];</span>
|
|
|
|
}
|
2015-05-05 12:56:18 -04:00
|
|
|
}
|
2015-05-19 17:31:43 -04:00
|
|
|
|
|
|
|
code-pane(language="javascript" name="Javascript (ES5)" format="linenums").
|
2015-05-19 09:33:09 -04:00
|
|
|
//ES5
|
|
|
|
function DisplayComponent() {
|
|
|
|
this.myName = "Alice";
|
2015-05-19 17:33:21 -04:00
|
|
|
<span class='otl'>this.names = ["Aarav", "Martín", "Shannon", "Ariana", "Kai"];</span>
|
2015-05-19 09:33:09 -04:00
|
|
|
}
|
2015-04-19 13:24:28 -04:00
|
|
|
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.
|
2015-05-05 12:56:18 -04:00
|
|
|
|
|
|
|
code-tabs
|
|
|
|
code-pane(language="javascript" name="TypeScript" format="linenums").
|
|
|
|
//Typescript
|
|
|
|
template: `
|
|
|
|
<p>My name: {{ myName }}</p>
|
|
|
|
<p>Friends:</p>
|
|
|
|
<ul>
|
|
|
|
<li *for="#name of names">
|
|
|
|
{{ name }}
|
|
|
|
</li>
|
|
|
|
</ul>
|
|
|
|
`,
|
2015-05-19 09:33:09 -04:00
|
|
|
code-pane(language="javascript" name="ES5" format="linenums").
|
|
|
|
//ES5
|
|
|
|
template:
|
|
|
|
'<p>My name: {{ myName }}</p>' +
|
|
|
|
'<p>Friends:</p>' +
|
|
|
|
'<ul>' +
|
|
|
|
'<li *for="#name of names">' +
|
|
|
|
'{{ name }}' +
|
|
|
|
'</li>' +
|
|
|
|
'</ul>',
|
2015-05-05 12:56:18 -04:00
|
|
|
|
2015-04-19 13:24:28 -04:00
|
|
|
p.
|
2015-05-05 01:14:09 -04:00
|
|
|
To make this work, you'll also need to add the <code>For</code> directive used by the template so
|
2015-04-19 13:24:28 -04:00
|
|
|
that Angular knows to include it:
|
2015-04-18 16:56:30 -04:00
|
|
|
|
2015-05-05 12:56:18 -04:00
|
|
|
code-tabs
|
|
|
|
code-pane(language="javascript" name="TypeScript" format="linenums").
|
|
|
|
//Typescript
|
2015-05-19 17:30:55 -04:00
|
|
|
import {Component, View, bootstrap, For} from 'angular2/angular2';
|
2015-05-19 17:33:21 -04:00
|
|
|
@View({
|
|
|
|
...
|
2015-05-19 09:33:09 -04:00
|
|
|
directives: [For]
|
2015-05-19 17:33:21 -04:00
|
|
|
})
|
|
|
|
|
2015-05-19 09:33:09 -04:00
|
|
|
|
|
|
|
code-pane(language="javascript" name="ES5" format="linenums").
|
|
|
|
//ES5
|
2015-05-19 17:33:21 -04:00
|
|
|
DisplayComponent.annotations = [
|
|
|
|
...
|
|
|
|
new angular.ViewAnnotation({
|
|
|
|
...
|
|
|
|
directives: [angular.For]
|
|
|
|
})
|
|
|
|
];
|
2015-05-05 12:56:18 -04:00
|
|
|
|
2015-04-19 13:24:28 -04:00
|
|
|
p Reload and you've got your list of friends!
|
|
|
|
p.
|
2015-05-19 17:28:26 -04:00
|
|
|
Angular will mirror changes you make to this list over in the DOM. Add a new item and it appears in your
|
2015-04-19 13:24:28 -04:00
|
|
|
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:
|
2015-05-19 09:33:09 -04:00
|
|
|
code-example(language="html" format="linenums").
|
|
|
|
//HTML
|
|
|
|
<li *for="#name of names">
|
|
|
|
{{ name }}
|
|
|
|
</li>
|
2015-04-19 13:24:28 -04:00
|
|
|
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
|
2015-05-19 17:33:21 -04:00
|
|
|
|
2015-04-19 13:24:28 -04:00
|
|
|
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.
|
2015-05-19 17:33:21 -04:00
|
|
|
|
2015-04-19 13:24:28 -04:00
|
|
|
p Make a <code>FriendsService</code> class to provide the model with the list of friends.
|
2015-05-19 09:33:09 -04:00
|
|
|
|
2015-05-19 17:33:21 -04:00
|
|
|
code-tabs
|
|
|
|
code-pane(language="javascript" name="TypeScript" format="linenums").
|
|
|
|
class FriendsService {
|
|
|
|
names: Array<string>;
|
|
|
|
constructor() {
|
|
|
|
this.names = ["Alice", "Aarav", "Martín", "Shannon", "Ariana", "Kai"];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
code-pane(language="javascript" name="ES5" format="linenums").
|
|
|
|
function FriendsService() {
|
|
|
|
this.names = ["Aarav", "Martín", "Shannon", "Ariana", "Kai"];
|
2015-05-19 09:33:09 -04:00
|
|
|
}
|
2015-04-19 13:24:28 -04:00
|
|
|
p.
|
2015-05-19 17:33:21 -04:00
|
|
|
Now replace the current list of friends in DisplayComponent by including the FriendsService in the injectables list,
|
|
|
|
then including the service in the constructor, and finally setting the list of
|
2015-04-19 13:24:28 -04:00
|
|
|
names in DisplayComponent to the names provided by the service you passed in.
|
2015-05-19 09:33:09 -04:00
|
|
|
|
2015-04-19 13:24:28 -04:00
|
|
|
.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.
|
2015-04-22 10:17:26 -04:00
|
|
|
|
2015-05-19 09:33:09 -04:00
|
|
|
code-tabs
|
|
|
|
code-pane(language="javascript" name="TypeScript" format="linenums").
|
2015-05-19 17:33:21 -04:00
|
|
|
@Component({
|
|
|
|
...
|
|
|
|
<span class='otl'>injectables: [FriendsService]</span>
|
|
|
|
})
|
|
|
|
class DisplayComponent {
|
|
|
|
myName: string;
|
2015-05-19 09:33:09 -04:00
|
|
|
names: Array<string>;
|
2015-05-19 17:33:21 -04:00
|
|
|
constructor(<span class='otl'>friendsService: FriendsService</span>) {
|
|
|
|
this.myName = 'Alice';
|
|
|
|
<span class='otl'>this.names = friendsService.names;</span>
|
2015-05-19 09:33:09 -04:00
|
|
|
}
|
|
|
|
}
|
2015-05-05 01:14:09 -04:00
|
|
|
|
2015-05-19 09:33:09 -04:00
|
|
|
code-pane(language="javascript" name="ES5" format="linenums").
|
|
|
|
//ES5
|
|
|
|
function FriendsService() {
|
|
|
|
this.names = ["Alice", "Aarav", "Martín", "Shannon", "Ariana", "Kai"];
|
|
|
|
}
|
2015-05-19 17:33:21 -04:00
|
|
|
function DisplayComponent(<span class='otl'>friends</span>) {
|
2015-05-19 09:33:09 -04:00
|
|
|
this.myName = "Alice";
|
2015-05-19 17:33:21 -04:00
|
|
|
this.names = <span class='otl'>friends.names</span>;
|
2015-05-19 09:33:09 -04:00
|
|
|
}
|
|
|
|
DisplayComponent.annotations = [
|
|
|
|
new angular.ComponentAnnotation({
|
|
|
|
selector: "display",
|
2015-05-19 17:33:21 -04:00
|
|
|
<span class='otl'>injectables: [FriendsService]</span>
|
2015-05-19 09:33:09 -04:00
|
|
|
}),
|
|
|
|
new angular.ViewAnnotation({
|
|
|
|
template: '{{ myName }} <ul> <li *for="#name of names">{{ name }}</li> </ul>',
|
2015-05-19 17:33:21 -04:00
|
|
|
directives: [angular.For]
|
2015-05-19 09:33:09 -04:00
|
|
|
})
|
|
|
|
];
|
2015-05-19 17:33:21 -04:00
|
|
|
<span class='otl'>DisplayComponent.parameters = [[FriendsService]];</span>
|
2015-05-19 09:33:09 -04:00
|
|
|
document.addEventListener("DOMContentLoaded", function() {
|
|
|
|
angular.bootstrap(DisplayComponent);
|
|
|
|
});
|
2015-04-19 13:24:28 -04:00
|
|
|
.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>
|
2015-05-05 01:14:09 -04:00
|
|
|
p You'll also need to add the <code>If</code> directive so Angular knows to include it.
|
2015-04-22 10:17:26 -04:00
|
|
|
|
2015-05-19 09:33:09 -04:00
|
|
|
code-tabs
|
|
|
|
code-pane(language="javascript" name="TypeScript" format="linenums").
|
|
|
|
//Typescript
|
2015-05-19 17:30:55 -04:00
|
|
|
import {Component, View, bootstrap, For, If} from 'angular2/angular2';
|
2015-05-19 09:33:09 -04:00
|
|
|
...
|
|
|
|
directives: [For, If]
|
|
|
|
code-pane(language="javascript" name="ES5" format="linenums").
|
|
|
|
//ES5
|
|
|
|
directives: [angular.For, angular.If]
|
2015-04-19 13:24:28 -04:00
|
|
|
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.
|
2015-05-19 09:33:09 -04:00
|
|
|
|
|
|
|
code-tabs
|
|
|
|
code-pane(language="javascript" name="TypeScript" format="linenums").
|
|
|
|
//TypeScript
|
|
|
|
import {Component, View, bootstrap, For, If} from 'angular2/angular2';
|
2015-05-19 18:09:37 -04:00
|
|
|
...
|
2015-05-19 09:33:09 -04:00
|
|
|
@View({
|
2015-05-19 18:09:37 -04:00
|
|
|
<span class='otl'>template</span>: `
|
2015-05-19 09:33:09 -04:00
|
|
|
<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 {
|
2015-05-19 18:09:37 -04:00
|
|
|
...
|
|
|
|
}
|
|
|
|
|
|
|
|
class FriendsService {
|
|
|
|
names: Array<string>;
|
2015-05-19 09:33:09 -04:00
|
|
|
constructor() {
|
2015-05-19 18:09:37 -04:00
|
|
|
<span class='otl'>this.names = ["Aarav", "Martín", "Shannon"];</span>
|
2015-05-19 09:33:09 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
code-pane(language="javascript" name="ES5" format="linenums").
|
|
|
|
//ES5
|
2015-05-19 18:09:37 -04:00
|
|
|
function DisplayComponent(friends) {
|
2015-05-19 09:33:09 -04:00
|
|
|
this.myName = "Alice";
|
2015-05-19 18:09:37 -04:00
|
|
|
this.names = friends.names;
|
2015-05-19 09:33:09 -04:00
|
|
|
}
|
|
|
|
DisplayComponent.annotations = [
|
2015-05-19 18:09:37 -04:00
|
|
|
...
|
2015-05-19 09:33:09 -04:00
|
|
|
new angular.ViewAnnotation({
|
2015-05-19 18:09:37 -04:00
|
|
|
<span class='otl'>template</span>: '
|
2015-05-19 09:33:09 -04:00
|
|
|
'<p>My name: {{ myName }}</p>' +
|
|
|
|
'<p>Friends:</p>' +
|
|
|
|
'<ul>' +
|
|
|
|
'<li *for="#name of names">' +
|
|
|
|
'{{ name }}' +
|
|
|
|
'</li>' +
|
|
|
|
'</ul>' +
|
2015-05-19 18:09:37 -04:00
|
|
|
'<p *if="names.length > 3">You have many friends!</p>'',
|
2015-05-19 09:33:09 -04:00
|
|
|
directives: [angular.For, angular.If]
|
|
|
|
})
|
|
|
|
];
|
2015-05-19 18:09:37 -04:00
|
|
|
|
|
|
|
function FriendsService () {
|
|
|
|
<span class='otl'>this.names = ["Aarav", "Martín", "Shannon"];</span>
|
|
|
|
}
|