Skip to content

Commit 3ee34e5

Browse files
committed
Updating the data binding section
1 parent 6042276 commit 3ee34e5

File tree

8 files changed

+16
-16
lines changed

8 files changed

+16
-16
lines changed

images/chapter3/android/1.png

12.6 KB
Loading

images/chapter3/android/2.png

34.7 KB
Loading

images/chapter3/android/3.png

34.4 KB
Loading

images/chapter3/ios/1.png

5.7 KB
Loading

images/chapter3/ios/2.png

-25.7 KB
Binary file not shown.

images/chapter3/ios/3.png

-26.2 KB
Binary file not shown.

index.html

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -589,11 +589,11 @@ <h4 class="exercise-start">
589589
<p><img src="images/chapter3/android/1.png" alt="Android with prefilled email">
590590
<img src="images/chapter3/ios/1.png" alt="iOS with prefilled email"></p>
591591
<blockquote>
592-
<p><strong>NOTE</strong>: It’s very easy to confuse Angular 2’s event binding syntax <code>(eventName)=&quot;functionName()&quot;</code> with its attribute binding syntax <code>[attributeName]=&quot;propertyName&quot;</code> 🤔. Don’t worry though; if you get them backwards, the problem is really 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>
592+
<p><strong>NOTE</strong>: It’s very easy to confuse Angular 2’s event binding syntax <code>(eventName)=&quot;functionName()&quot;</code> with its attribute binding syntax <code>[attributeName]=&quot;propertyName&quot;</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>
593593
</blockquote>
594-
<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—and actually, it’s far easier to show this limitation in the current code.</p>
595-
<p>Head back to your app, change the text field value (type a few extra letters or something like that), and then tap the Sign In button. Because your <code>signIn()</code> function alerts the current value of your component’s <code>email</code> property—<code>alert(&quot;You’re using: &quot; + 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>
596-
<p><img src="images/chapter3/ios/2.png" alt="iOS with email address that doesn’t match"></p>
594+
<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>
595+
<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>signIn()</code> function alerts the current value of your component’s <code>email</code> property—<code>alert(&quot;You’re using: &quot; + 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>
596+
<p><img src="images/chapter3/android/2.png" alt="Android with email address that do not match"></p>
597597
<p>To fix this, you need to switch to Angular 2’s two-way data binding syntax.</p>
598598
<h4 class="exercise-start">
599599
<b>Exercise</b>: Two-way data binding with Angular 2
@@ -605,13 +605,13 @@ <h4 class="exercise-start">
605605
</code></pre>
606606
<div class="exercise-end"></div>
607607

608-
<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. And that’s because the syntax actually is a shorthand for both an attribute binding and an event binding, or in code—<code>[text]=&quot;email&quot; (emailChange)=&quot;email=$event&quot;</code>, which binds a text field’s <code>text</code> attribute property to an <code>email</code> property, as well as adds a <code>change</code> event handler that updates the <code>email</code> property’s value whenever the user makes a change.</p>
609-
<p>And, 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>
610-
<p><img src="images/chapter3/ios/3.png" alt="iOS with email address that does match"></p>
608+
<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)]=&quot;email&quot;</code> is shorthand for <code>[text]=&quot;email&quot; (emailChange)=&quot;email=$event&quot;</code>, which binds the email element’s <code>text</code> attribute to an <code>email</code> property, as well as adds a <code>change</code> event handler that updates the <code>email</code> property’s value whenever the user makes a change.</p>
609+
<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. And 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>
610+
<p><img src="images/chapter3/android/3.png" alt="Android with email addresses that do match"></p>
611611
<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>
612612
<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>
613613
<h3 id="structuring-your-app">Structuring your app</h3>
614-
<p>There are many reasons to segment your application into modular units, and you can <a href="https://en.wikipedia.org/wiki/Modular_programming">read about the various benefits on Wikipedia</a>. However, keeping NativeScript apps modular has one unique benefit: the ability to share the code you write between Angular-2-built web apps, and Angular-2-build native apps.</p>
614+
<p>There are many reasons to segment any application into modular units, and you can <a href="https://en.wikipedia.org/wiki/Modular_programming">read about the various benefits on Wikipedia</a>. However, keeping NativeScript apps modular has one unique benefit: the ability to share the code you write between Angular-2-built web apps, and Angular-2-build native apps.</p>
615615
<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 for your native and web apps can be an invaluable time saver.</p>
616616
<p>To see how this works in action let’s edit some files in the <code>/shared</code> folder and set them up to be imported.</p>
617617
<h4 class="exercise-start">

src/chapters/chapter3.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,13 @@ The key thing to note here is the `[text]="email"` attribute on the `<TextField>
7575
![Android with prefilled email](images/chapter3/android/1.png)
7676
![iOS with prefilled email](images/chapter3/ios/1.png)
7777

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 really 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.
7979
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—and actually, it’s far easier to show this limitation in the current 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 be reflected in your TypeScript code.
8181

82-
Head back to your app, change the text field value (type a few extra letters or something like that), and then tap the Sign In button. Because your `signIn()` 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.
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 `signIn()` 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.
8383

84-
![iOS with email address that doesn’t match](images/chapter3/ios/2.png)
84+
![Android with email address that do not match](images/chapter3/android/2.png)
8585

8686
To fix this, you need to switch to Angular 2’s two-way data binding syntax.
8787

@@ -98,19 +98,19 @@ In `app/app.component.ts`, find the find the first `<TextField>`, and replace it
9898

9999
<div class="exercise-end"></div>
100100

101-
At first glance the `[(ngModel)]` 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. And that’s because the syntax actually is a shorthand for both an attribute binding and an event binding, or in code—`[text]="email" (emailChange)="email=$event"`, which binds a text field’s `text` attribute property to an `email` property, as well as adds a `change` event handler that updates the `email` property’s value whenever the user makes a change.
101+
At first glance the `[(ngModel)]` 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, `[(ngModel)]="email"` is shorthand for `[text]="email" (emailChange)="email=$event"`, which binds the email element’s `text` attribute to an `email` property, as well as adds a `change` event handler that updates the `email` property’s value whenever the user makes a change.
102102

103-
And, 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:
103+
Don’t worry too much about the details here while we’re still getting started. In your head you can think of `[(ngModel)]` as the way to implement two-way data binding when you need it on form controls. And 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:
104104

105-
![iOS with email address that does match](images/chapter3/ios/3.png)
105+
![Android with email addresses that do match](images/chapter3/android/3.png)
106106

107107
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.
108108

109109
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.
110110

111111
### Structuring your app
112112

113-
There are many reasons to segment your application into modular units, and you can [read about the various benefits on Wikipedia](https://en.wikipedia.org/wiki/Modular_programming). However, keeping NativeScript apps modular has one unique benefit: the ability to share the code you write between Angular-2-built web apps, and Angular-2-build native apps.
113+
There are many reasons to segment any application into modular units, and you can [read about the various benefits on Wikipedia](https://en.wikipedia.org/wiki/Modular_programming). However, keeping NativeScript apps modular has one unique benefit: the ability to share the code you write between Angular-2-built web apps, and Angular-2-build native apps.
114114

115115
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 _do_ have plans to build an Angular 2 web app, having a chunk of functionality that you can reuse for your native and web apps can be an invaluable time saver.
116116

0 commit comments

Comments
 (0)