You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: index.html
+22-27Lines changed: 22 additions & 27 deletions
Original file line number
Diff line number
Diff line change
@@ -586,7 +586,7 @@ <h4 class="exercise-start">
586
586
587
587
<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>
588
588
<pre><codeclass="lang-TypeScript">export class AppComponent {
<p><imgsrc="images/chapter3/android/1.png" alt="Android with prefilled email">
603
603
<imgsrc="images/chapter3/ios/1.png" alt="iOS with prefilled email"></p>
604
604
<blockquote>
605
-
<p><strong>NOTE</strong>: It’s very easy to confuse Angular 2’s event binding syntax <code>(eventName)="functionName()"</code> with its attribute binding syntax <code>[attributeName]="propertyName"</code> 🤔. Don’t worry though; if you get them backwards, the problem is usually easy to debug, as the functionality you’re attempting to add just won’t work. These syntaxes are common enough that you’ll be using them a lot, and eventually you should be able to commit them to memory.</p>
605
+
<p><strong>NOTE</strong>: It’s very easy to confuse Angular 2’s event binding syntax <code>(eventName)="functionName()"</code> with its attribute binding syntax <code>[attributeName]="propertyName"</code>. Don’t worry though; if you get them backwards, the problem is usually easy to debug, as the functionality you’re attempting to add just won’t work. These syntaxes are common enough that you’ll be using them a lot, and eventually you should be able to commit them to memory.</p>
606
606
</blockquote>
607
-
<p>This attribute binding approach works really well when you need the data binding to be one way—that is, when you need TypeScript properties, and changes to those properties done in TypeScript code, to appear in the user interface. But in the case of user interface controls that accept user input, such as the text field in this example, usually you need data binding to work two way—that is, you additionally need changes the user makes to be reflected in your TypeScript code.</p>
607
+
<p>This attribute binding approach works really well when you need the data binding to be one way—that is, when you need TypeScript properties, and changes to those properties done in TypeScript code, to appear in the user interface. But in the case of user interface controls that accept user input, such as the text field in this example, usually you need data binding to work two way—that is, you additionally need changes the user makes to data via form controls to be reflected in your TypeScript code.</p>
608
608
<p>To show that the current example’s data binding is only one way, head back to your app, change the email text field’s value (type a few extra letters or something like that), and then tap the “Sign In” button. Because your <code>submit()</code> function alerts the current value of your component’s <code>email</code> property—<code>alert("You’re using: " + this.email)</code>—you might expect to see the updated value in the alert. Instead, however, you see the original value. Notice how the typed text and the alert value don’t match in the screenshot below.</p>
609
609
<p><imgsrc="images/chapter3/android/2.png" alt="Android with email address that do not match"></p>
610
610
<p>To fix this, you need to switch to Angular 2’s two-way data binding syntax.</p>
@@ -621,40 +621,35 @@ <h4 class="exercise-start">
621
621
<p>At first glance the <code>[(ngModel)]</code> syntax looks more than a little odd, as it’s essentially a combination of the event and attribute binding syntax that you used in earlier examples. In the case of this example, <code>[(ngModel)]="email"</code> is shorthand for <code>[text]="email" (emailChange)="email=$event"</code>, which binds the email element’s <code>text</code> attribute to an <code>email</code> property and adds a <code>change</code> event handler that updates the <code>email</code> property’s value whenever the user makes a change.</p>
622
622
<p>Don’t worry too much about the details here while we’re still getting started. In your head you can think of <code>[(ngModel)]</code> as the way to implement two-way data binding when you need it on form controls. To show that it works, if you again modify your app’s email address and click the “Sign In” button, you’ll see the updated value in the alert as expected:</p>
623
623
<p><imgsrc="images/chapter3/android/3.png" alt="Android with email addresses that do match"></p>
624
-
<p>At this point, you have a basic login screen setup with two-way data binding—not bad for 20 some lines of code of TypeScript. (Think about how much code you’d have to write in Android Studio <em>and</em> Xcode to accomplish the same task.) To this point though you’ve been placing all of your logic in a single TypeScript file, which doesn’t scale all that well for real-world applications.</p>
625
-
<p>Before we tie this app to a backend and make this login screen fully functional, let’s take a step back and setup a structure that can scale.</p>
626
-
<!--commenting this out as I don't think it belongs here. We just said we're going to move code out of the single file, then we start talking about more stuff to add to the single file...confuzzled-->
627
-
<!--<h4 class="exercise-start">
628
-
<b>Exercise</b>: ???
624
+
<p>Before we move on, let’s make one additional change to show what else you can do with Angular 2’s data binding APIs. The Groceries app uses the same UI for the “Sign In” form and the “Sign Up” form. Therefore, when the user clicks “Sign Up”, we need to update the text of the buttons (and eventually the functionality that occurs when you tap them). Let’s see how to make that happen.</p>
625
+
<h4class="exercise-start">
626
+
<b>Exercise</b>: Using the ternary operator in templates
629
627
</h4>
630
628
631
-
app.component.ts — Replace the two buttons with this
<Button [text]="isLoggingIn ? 'Sign up' : 'Back to login'" (tap)="toggleDisplay()"></Button>
632
+
</code></pre>
633
+
<p>Next, replace the existing <code>AppComponent</code> declaration with the code below, which adds a new <code>isLoggingIn</code> property, and a new <code>toggleDisplay()</code> method:</p>
634
+
<pre><codeclass="lang-TypeScript">export class AppComponent {
<p>The previous examples switches each button’s’ <code>text</code> attribute from a simple string—e.g. <code><Button text="Sign Up"></code>—to an attribute binding that is dependent on a value defined in the <code>AppComponent</code> class—e.g. <code><Button [text]="isLoggingIn ? 'Sign in' : 'Sign up'">"</code>. Now, when the value of the <code>isLoggingIn</code> attributes changes after the user clicks the bottom button, Angular is smart enough to update the text of the button automatically. The result looks like this:</p>
649
+
<p><imgsrc="images/chapter3/android/4.gif" alt="Text changing on Android">
650
+
<imgsrc="images/chapter3/ios/4.gif" alt="Text changing on iOS"></p>
651
+
<p>At this point, you have a basic login screen setup with two-way data binding—which isn’t bad for 20 some lines of code of TypeScript. (Think about how much code you’d have to write in Android Studio <em>and</em> Xcode to accomplish the same task.) To this point though you’ve been placing all of your logic in a single TypeScript file, which doesn’t scale all that well for real-world applications.</p>
652
+
<p>Before we tie this app to a backend and make this login screen fully functional, let’s take a step back and setup a structure that can scale.</p>
658
653
<h3id="structuring-your-app">Structuring your app</h3>
659
654
<p>There are many reasons to segment any application into modular units, and you can <ahref="https://en.wikipedia.org/wiki/Modular_programming">read about the various benefits on Wikipedia</a>. Modularizing NativeScript apps, in addition, has one unique benefit: the ability to share the code you write between Angular-2-built web apps, and Angular-2-built native apps.</p>
660
655
<p>Even if you have no plans to create an Angular 2 web app, separating out your code is still advantageous for a number of other reasons—testability, ease of maintenance, and so forth—but if you <em>do</em> have plans to build an Angular 2 web app, having a chunk of functionality that you can reuse in your native and web apps can be an invaluable time saver.</p>
@@ -810,7 +805,7 @@ <h4 class="exercise-start">
810
805
<p>Create an account, then hardcode those credentials in your constructor to make testing easier:</p>
Copy file name to clipboardExpand all lines: src/chapters/chapter3.md
+17-15Lines changed: 17 additions & 15 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -54,7 +54,7 @@ In `app/app.component.ts` replace the current `AppComponent` declaration with th
54
54
55
55
```TypeScript
56
56
exportclassAppComponent {
57
-
email ="user@nativescript.org";
57
+
email ="nativescriptrocks@telerik.com";
58
58
submit() {
59
59
alert("You’re using: "+this.email);
60
60
}
@@ -75,9 +75,9 @@ The key thing to note here is the `[text]="email"` attribute on the `<TextField>
75
75

76
76

77
77
78
-
> **NOTE**: It’s very easy to confuse Angular 2’s event binding syntax `(eventName)="functionName()"` with its attribute binding syntax `[attributeName]="propertyName"` 🤔. Don’t worry though; if you get them backwards, the problem is usually easy to debug, as the functionality you’re attempting to add just won’t work. These syntaxes are common enough that you’ll be using them a lot, and eventually you should be able to commit them to memory.
78
+
> **NOTE**: It’s very easy to confuse Angular 2’s event binding syntax `(eventName)="functionName()"` with its attribute binding syntax `[attributeName]="propertyName"`. Don’t worry though; if you get them backwards, the problem is usually easy to debug, as the functionality you’re attempting to add just won’t work. These syntaxes are common enough that you’ll be using them a lot, and eventually you should be able to commit them to memory.
79
79
80
-
This attribute binding approach works really well when you need the data binding to be one way—that is, when you need TypeScript properties, and changes to those properties done in TypeScript code, to appear in the user interface. But in the case of user interface controls that accept user input, such as the text field in this example, usually you need data binding to work two way—that is, you additionally need changes the user makes to be reflected in your TypeScript code.
80
+
This attribute binding approach works really well when you need the data binding to be one way—that is, when you need TypeScript properties, and changes to those properties done in TypeScript code, to appear in the user interface. But in the case of user interface controls that accept user input, such as the text field in this example, usually you need data binding to work two way—that is, you additionally need changes the user makes to data via form controls to be reflected in your TypeScript code.
81
81
82
82
To show that the current example’s data binding is only one way, head back to your app, change the email text field’s value (type a few extra letters or something like that), and then tap the “Sign In” button. Because your `submit()` function alerts the current value of your component’s `email` property—`alert("You’re using: " + this.email)`—you might expect to see the updated value in the alert. Instead, however, you see the original value. Notice how the typed text and the alert value don’t match in the screenshot below.
83
83
@@ -104,27 +104,25 @@ Don’t worry too much about the details here while we’re still getting starte
104
104
105
105

106
106
107
-
At this point, you have a basic login screen setup with two-way data binding—not bad for 20 some lines of code of TypeScript. (Think about how much code you’d have to write in Android Studio _and_ Xcode to accomplish the same task.) To this point though you’ve been placing all of your logic in a single TypeScript file, which doesn’t scale all that well for real-world applications.
107
+
Before we move on, let’s make one additional change to show what else you can do with Angular 2’s data binding APIs. The Groceries app uses the same UI for the “Sign In” form and the “Sign Up” form. Therefore, when the user clicks “Sign Up”, we need to update the text of the buttons (and eventually the functionality that occurs when you tap them). Let’s see how to make that happen.
108
108
109
-
Before we tie this app to a backend and make this login screen fully functional, let’s take a step back and setup a structure that can scale.
110
109
111
-
<!--commenting this out as I don't think it belongs here. We just said we're going to move code out of the single file, then we start talking about more stuff to add to the single file...confuzzled-->
112
-
<!--<h4 class="exercise-start">
113
-
<b>Exercise</b>: ???
110
+
<h4class="exercise-start">
111
+
<b>Exercise</b>: Using the ternary operator in templates
114
112
</h4>
115
113
116
-
app.component.ts — Replace the two buttons with this
114
+
Open `app/app.component.ts` and replace the two existing buttons with the code below:
<Button [text]="isLoggingIn ? 'Sign up' : 'Back to login'" (tap)="toggleDisplay()"></Button>
121
119
```
122
120
123
-
app.component.ts - Use this for the AppComponent class:
121
+
Next, replace the existing `AppComponent` declaration with the code below, which adds a new `isLoggingIn` property, and a new `toggleDisplay()` method:
124
122
125
123
```TypeScript
126
124
exportclassAppComponent {
127
-
email = "user@nativescript.org";
125
+
email ="nativescriptrocks@telerik.com";
128
126
isLoggingIn =true;
129
127
130
128
submit() {
@@ -138,10 +136,14 @@ export class AppComponent {
138
136
139
137
<divclass="exercise-end"></div>
140
138
141
-
TODO: Transition
142
-
-->
139
+
The previous examples switches each button’s’ `text` attribute from a simple string—e.g. `<Button text="Sign Up">`—to an attribute binding that is dependent on a value defined in the `AppComponent` class—e.g. `<Button [text]="isLoggingIn ? 'Sign in' : 'Sign up'">"`. Now, when the value of the `isLoggingIn` attributes changes after the user clicks the bottom button, Angular is smart enough to update the text of the button automatically. The result looks like this:
143
140
141
+

142
+

144
143
144
+
At this point, you have a basic login screen setup with two-way data binding—which isn’t bad for 20 some lines of code of TypeScript. (Think about how much code you’d have to write in Android Studio _and_ Xcode to accomplish the same task.) To this point though you’ve been placing all of your logic in a single TypeScript file, which doesn’t scale all that well for real-world applications.
145
+
146
+
Before we tie this app to a backend and make this login screen fully functional, let’s take a step back and setup a structure that can scale.
145
147
146
148
### Structuring your app
147
149
@@ -346,7 +348,7 @@ Create an account, then hardcode those credentials in your constructor to make t
0 commit comments