Skip to content

Commit eb228fd

Browse files
committed
Finishing the discussion on ListViews
1 parent 6f4ee14 commit eb228fd

File tree

3 files changed

+386
-8
lines changed

3 files changed

+386
-8
lines changed

index.html

Lines changed: 168 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ <h4 class="exercise-start">
572572

573573
<p>In <code>app/app.component.ts</code> replace the current <code>AppComponent</code> declaration with the one shown below, which adds a new <code>email</code> property, and changes the <code>submit()</code> method to display its value:</p>
574574
<pre><code class="lang-TypeScript">export class AppComponent {
575-
email = &quot;nativescriptrocks@telerik.com&quot;;
575+
email = &quot;user@nativescript.org&quot;;
576576
submit() {
577577
alert(&quot;You’re using: &quot; + this.email);
578578
}
@@ -619,7 +619,7 @@ <h4 class="exercise-start">
619619
</code></pre>
620620
<p>app.component.ts - Use this for the AppComponent class:</p>
621621
<pre><code class="lang-TypeScript">export class AppComponent {
622-
email = &quot;nativescriptrocks@telerik.com&quot;;
622+
email = &quot;user@nativescript.org&quot;;
623623
isLoggingIn = true;
624624

625625
submit() {
@@ -788,7 +788,7 @@ <h4 class="exercise-start">
788788
<p>Create an account, then hardcode those credentials in your constructor to make testing easier:</p>
789789
<pre><code class="lang-TypeScript">constructor(private _userService: UserService) {
790790
this.user = new User();
791-
this.user.email = &quot;nativescriptrocks@telerik.com&quot;;
791+
this.user.email = &quot;user@nativescript.org&quot;;
792792
this.user.password = &quot;password&quot;;
793793
}
794794
</code></pre>
@@ -810,7 +810,7 @@ <h4 class="exercise-start">
810810

811811
constructor(private _userService: UserService) {
812812
this.user = new User();
813-
this.user.email = &quot;nativescriptrocks@telerik.com&quot;;
813+
this.user.email = &quot;user@nativescript.org&quot;;
814814
this.user.password = &quot;password&quot;;
815815
}
816816
submit() {
@@ -994,6 +994,170 @@ <h4 class="exercise-start">
994994

995995
<p>Talk about the color module and animation module. Have gifs. Mention that the hint color looks bad, but that we’ll address that later. Transition to talking about the list page.</p>
996996
<h3 id="listview">ListView</h3>
997+
<p>Talk about what list views are.</p>
998+
<h4 class="exercise-start">
999+
<b>Exercise</b>: ???
1000+
</h4>
1001+
1002+
<p>Open <code>app/pages/list/list.html</code> and paste in the following code:</p>
1003+
<pre><code class="lang-XML">&lt;ListView [items]=&quot;groceryList&quot; class=&quot;small-spacing&quot;&gt;
1004+
&lt;template #item=&quot;item&quot;&gt;
1005+
&lt;Label [text]=&quot;item.name&quot; class=&quot;medium-spacing&quot;&gt;&lt;/Label&gt;
1006+
&lt;/template&gt;
1007+
&lt;/ListView&gt;
1008+
</code></pre>
1009+
<p>We’ll talk about the syntax in a moment, for now concentrate on the new <code>class</code> attribute. Open <code>app/app.css</code> and paste the following code at the bottom of the file:</p>
1010+
<pre><code class="lang-CSS">.small-spacing {
1011+
margin: 5;
1012+
}
1013+
.medium-spacing {
1014+
margin: 10;
1015+
}
1016+
</code></pre>
1017+
<p>Next, open <code>app/pages/list/list.component.ts</code> and paste in the following code:</p>
1018+
<pre><code class="lang-TypeScript">import {Component, OnInit} from &quot;angular2/core&quot;;
1019+
1020+
@Component({
1021+
selector: &quot;list&quot;,
1022+
templateUrl: &quot;pages/list/list.html&quot;,
1023+
styleUrls: [&quot;pages/list/list-common.css&quot;, &quot;pages/list/list.css&quot;]
1024+
})
1025+
export class ListPage implements OnInit {
1026+
groceryList: Array&lt;Object&gt; = [];
1027+
1028+
ngOnInit() {
1029+
this.groceryList.push({ name: &quot;Apples&quot; });
1030+
this.groceryList.push({ name: &quot;Bananas&quot; });
1031+
this.groceryList.push({ name: &quot;Oranges&quot; });
1032+
}
1033+
}
1034+
</code></pre>
1035+
<div class="exercise-end"></div>
1036+
1037+
<p>Break down the new XML and TypeScript code individually.</p>
1038+
<p>This list is hardcoded which isn’t a whole lot of fun.</p>
1039+
<h4 class="exercise-start">
1040+
<b>Exercise</b>: ???
1041+
</h4>
1042+
1043+
<p>Open <code>app/shared/grocery/grocery.ts</code> and paste in the following code:</p>
1044+
<pre><code class="lang-TypeScript">export class Grocery {
1045+
constructor(public id: string, public name: string) {}
1046+
}
1047+
</code></pre>
1048+
<p>Open <code>app/shared/grocery/grocery-list.service.ts</code> and paste in the following code:</p>
1049+
<pre><code class="lang-TypeScript">import {Injectable} from &quot;angular2/core&quot;;
1050+
import {Http, Headers} from &quot;angular2/http&quot;;
1051+
import {Config} from &quot;../config&quot;;
1052+
import {Grocery} from &quot;./grocery&quot;;
1053+
import {Observable} from &quot;rxjs/Rx&quot;;
1054+
import &quot;rxjs/add/operator/map&quot;;
1055+
1056+
@Injectable()
1057+
export class GroceryListService {
1058+
constructor(private _http: Http) {}
1059+
1060+
load() {
1061+
var headers = new Headers();
1062+
headers.append(&quot;Authorization&quot;, &quot;Bearer &quot; + Config.token);
1063+
1064+
return this._http.get(Config.apiUrl + &quot;Groceries&quot;, {
1065+
headers: headers
1066+
})
1067+
.map(res =&gt; res.json())
1068+
.map(data =&gt; {
1069+
var groceryList = [];
1070+
data.Result.forEach((grocery) =&gt; {
1071+
groceryList.push(new Grocery(grocery.Id, grocery.Name));
1072+
});
1073+
return groceryList;
1074+
})
1075+
.catch(this.handleErrors);
1076+
}
1077+
1078+
handleErrors(error: Response) {
1079+
console.log(JSON.stringify(error.json()));
1080+
return Observable.throw(error);
1081+
}
1082+
}
1083+
</code></pre>
1084+
<p>Open <code>app/pages/list/list.component.ts</code> and add the following two lines to the top of the file:</p>
1085+
<pre><code class="lang-TypeScript">import {Grocery} from &quot;../../shared/grocery/grocery&quot;;
1086+
import {GroceryListService} from &quot;../../shared/grocery/grocery-list.service&quot;;
1087+
</code></pre>
1088+
<p>Next, change the existing <code>groceryList</code> declaration to use the newly imported <code>Grocery</code> class instead of a generic <code>Object</code>:</p>
1089+
<pre><code class="lang-TypeScript">groceryList: Array&lt;Grocery&gt; = [];
1090+
</code></pre>
1091+
<p>Then, add the following <code>constructor</code> function within the <code>ListPage</code> class:</p>
1092+
<pre><code class="lang-TypeScript">constructor(private _groceryListService: GroceryListService) {}
1093+
</code></pre>
1094+
<p>Because we’re injecting a service we must also add it as a provider within our component decorator:</p>
1095+
<pre><code class="lang-TypeScript">@Component({
1096+
selector: &quot;list&quot;,
1097+
templateUrl: &quot;pages/list/list.html&quot;,
1098+
styleUrls: [&quot;pages/list/list-common.css&quot;, &quot;pages/list/list.css&quot;],
1099+
providers: [GroceryListService]
1100+
})
1101+
</code></pre>
1102+
<p>Finally, replace the existing <code>ngOnInit()</code> function with the code below:</p>
1103+
<pre><code class="lang-TypeScript">ngOnInit() {
1104+
this._groceryListService.load()
1105+
.subscribe(loadedGroceries =&gt; {
1106+
loadedGroceries.forEach((groceryObject) =&gt; {
1107+
this.groceryList.unshift(groceryObject);
1108+
});
1109+
});
1110+
}
1111+
</code></pre>
1112+
<p>The full version of your <code>app/pages/list/list.component.ts</code> file should now look like this:</p>
1113+
<pre><code class="lang-TypeScript">import {Component, OnInit} from &quot;angular2/core&quot;;
1114+
1115+
import {Grocery} from &quot;../../shared/grocery/grocery&quot;;
1116+
import {GroceryListService} from &quot;../../shared/grocery/grocery-list.service&quot;;
1117+
1118+
@Component({
1119+
selector: &quot;list&quot;,
1120+
templateUrl: &quot;pages/list/list.html&quot;,
1121+
styleUrls: [&quot;pages/list/list-common.css&quot;, &quot;pages/list/list.css&quot;],
1122+
providers: [GroceryListService]
1123+
})
1124+
export class ListPage implements OnInit {
1125+
groceryList: Array&lt;Grocery&gt; = [];
1126+
1127+
constructor(private _groceryListService: GroceryListService) {}
1128+
1129+
ngOnInit() {
1130+
this._groceryListService.load()
1131+
.subscribe(loadedGroceries =&gt; {
1132+
loadedGroceries.forEach((groceryObject) =&gt; {
1133+
this.groceryList.unshift(groceryObject);
1134+
});
1135+
});
1136+
}
1137+
}
1138+
</code></pre>
1139+
<div class="exercise-end"></div>
1140+
1141+
<p>Talk about the code you just added. But then note that if you try the code, you’ll get an exception about no provider for Http. Talk about best practices of where to declare shared providers. Let’s fix the problem now.</p>
1142+
<h4 class="exercise-start">
1143+
<b>Exercise</b>: ???
1144+
</h4>
1145+
1146+
<p>Open <code>app/pages/login/login.component.ts</code> and <em>remove</em> the following line from the top of the file:</p>
1147+
<pre><code class="lang-TypeScript">import {HTTP_PROVIDERS} from &quot;angular2/http&quot;;
1148+
</code></pre>
1149+
<p>Next, in the same file, remove <code>HTTP_PROVIDERS</code> from the component decorator’s <code>providers</code> array. The array should now look this like:</p>
1150+
<pre><code class="lang-TypeScript">providers: [UserService]
1151+
</code></pre>
1152+
<p>After that, open <code>app/app.component.ts</code> and <em>add</em> the following import to the top of the file:</p>
1153+
<pre><code class="lang-TypeScript">import {HTTP_PROVIDERS} from &quot;angular2/http&quot;;
1154+
</code></pre>
1155+
<p>Finally, add <code>HTTP_PROVIDERS</code> to the <code>AppComponent</code> decorator’s <code>providers</code> array so that it looks like this:</p>
1156+
<pre><code class="lang-TypeScript">providers: [HTTP_PROVIDERS, NS_ROUTER_PROVIDERS],
1157+
</code></pre>
1158+
<div class="exercise-end"></div>
1159+
1160+
<p>Show an image of the list with backend-driven data. Talk about how the next step is letting users add to the list.</p>
9971161
<h3 id="gridlayout">GridLayout</h3>
9981162
<h3 id="activityindicator">ActivityIndicator</h3>
9991163

src/chapters/chapter3.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ In `app/app.component.ts` replace the current `AppComponent` declaration with th
5454

5555
``` TypeScript
5656
export class AppComponent {
57-
email = "nativescriptrocks@telerik.com";
57+
email = "user@nativescript.org";
5858
submit() {
5959
alert("You’re using: " + this.email);
6060
}
@@ -123,7 +123,7 @@ app.component.ts - Use this for the AppComponent class:
123123

124124
``` TypeScript
125125
export class AppComponent {
126-
email = "nativescriptrocks@telerik.com";
126+
email = "user@nativescript.org";
127127
isLoggingIn = true;
128128

129129
submit() {
@@ -345,7 +345,7 @@ Create an account, then hardcode those credentials in your constructor to make t
345345
``` TypeScript
346346
constructor(private _userService: UserService) {
347347
this.user = new User();
348-
this.user.email = "nativescriptrocks@telerik.com";
348+
this.user.email = "user@nativescript.org";
349349
this.user.password = "password";
350350
}
351351
```
@@ -370,7 +370,7 @@ export class AppComponent {
370370

371371
constructor(private _userService: UserService) {
372372
this.user = new User();
373-
this.user.email = "nativescriptrocks@telerik.com";
373+
this.user.email = "user@nativescript.org";
374374
this.user.password = "password";
375375
}
376376
submit() {

0 commit comments

Comments
 (0)