1
1
---
2
2
title : Data Binding in NativeScript
3
+ contributors :
4
+ - Ombuweb
5
+ - flipperlite
3
6
---
4
7
5
8
_ Data Binding_ refers to a connection (_ binding_ ) and data flow between _ ViewModel_ (Model) and _ User Interface_ (UI).
@@ -22,28 +25,42 @@ There are various ways to manage data flow, often referred to as data bindings:
22
25
23
26
``` ts
24
27
export class HelloWorldModel extends Observable {
25
- name = " John Doe"
26
-
27
- ...
28
-
28
+ name = ' John Doe'
29
29
}
30
30
```
31
31
32
- - ** One-way (to Model) data binding** - Binding which updates the model in relation to some action in the UI. The best example for this is a [ tap] ( /guide/gestures#tap-gesture ) event.
32
+ - ** One-way (to Model) data binding** - Binding which updates the model in relation to some action in the UI. The best example for this is a [ tap] ( /guide/gestures#tap-gesture ) event. Static and data bound arguments can be passed using [ function currying ] ( https://javascript.info/currying-partials ) . Here's a [ working example ] ( https://stackblitz.com/edit/nativescript-stackblitz-templates-f6wmfx?file=app%2Fmain-view-model.ts ) .
33
33
34
34
``` xml
35
35
<Button text =" Submit" tap =" {{ onTap }}" />
36
+
37
+ <Button text =" Button 1" tap =" {{ onTap2('Button 1') }}" />
38
+ <Button text =" Button 2" tap =" {{ onTap2('Button 2') }}" />
39
+
40
+ <Button text =" Button 3" tap =" {{ onTap3('Button 3', counter) }}" />
36
41
```
37
42
38
43
``` ts
39
44
export class HelloWorldModel extends Observable {
45
+ public counter: number = 42
40
46
41
- onTap(args : EventData ){
42
-
43
- }
47
+ onTap(args : EventData ) {
48
+ //
49
+ }
44
50
45
- ...
51
+ onTap2(source : string ) {
52
+ return function fnOnTap2(args : EventData ) {
53
+ console .log (' onTap2.source =' , source )
54
+ }
55
+ }
46
56
57
+ onTap3(source : string , num : number ) {
58
+ return (args : EventData ) => {
59
+ console .log (' onTap3.source =' , source )
60
+ console .log (' onTap3.num =' , num )
61
+ this .counter --
62
+ }
63
+ }
47
64
}
48
65
```
49
66
@@ -55,10 +72,7 @@ export class HelloWorldModel extends Observable {
55
72
56
73
``` ts
57
74
export class HelloWorldModel extends Observable {
58
- name = " John Doe"
59
-
60
- ...
61
-
75
+ name = ' John Doe'
62
76
}
63
77
```
64
78
@@ -92,129 +106,89 @@ NativeScript supports the following polymorphic binding expressions:
92
106
To access a value stored in an object property of the bindingContext, use the propert access expression:
93
107
94
108
``` ts
95
- ...
96
109
user = {
97
- names:{
98
- first: " Sara"
99
- }
110
+ names: {
111
+ first: ' Sara' ,
112
+ },
100
113
}
101
- ...
102
114
```
103
115
104
116
``` xml
105
-
106
117
<Label text =" {{ user.name.first }}" textWrap =" true" />
107
-
108
118
```
109
119
110
- ---
111
-
112
120
### array access
113
121
114
122
``` xml
115
-
116
123
<Label text =" {{ fruits[0] }}" textWrap =" true" />
117
-
118
124
```
119
125
120
- ---
121
-
122
126
### logical operators
123
127
124
128
You can use the not(` ! ` ) operator to reverse the logical state of a binding context property.
125
129
126
130
``` xml
127
-
128
131
<Label text =" {{ !isUserLoggedIn }}" textWrap =" true" />
129
-
130
132
```
131
133
132
134
Supported operators: ` && ` , ` || ` and ` ! ` .
133
135
134
- ---
135
-
136
136
### unary operators
137
137
138
138
``` xml
139
-
140
139
<Label text =" {{ +age }}" textWrap =" true" />
141
-
142
140
```
143
141
144
142
``` ts
145
-
146
- ...
147
-
148
- age = " 33"
149
-
143
+ age = ' 33'
150
144
```
151
145
152
146
Converts a property value to a ` number ` . To convert a property to a ` number ` and negate it, use the ` - ` operator.
153
147
154
- ---
155
-
156
148
### comparison operators
157
149
158
150
``` xml
159
-
160
151
<Label text =" {{ prop1 > prop2 }}" textWrap =" true" />
161
-
162
152
```
163
153
164
154
Supported operators: ` > ` ,` < ` , ` <= ` , ` >= ` , ` == ` , ` != ` , ` === ` , ` !== ` .
165
155
166
- ---
167
-
168
156
### ternary operator
169
157
170
158
``` xml
171
-
172
159
<Label text =" {{ prop1 ? prop2 : prop3 }}" textWrap =" true" />
173
-
174
160
```
175
161
176
- ---
177
-
178
162
### grouping parenthesis
179
163
180
164
``` xml
181
-
182
165
<Label text =" {{ prop1*(prop2 + prop3) }}" textWrap =" true" />
183
-
184
166
```
185
167
186
- ---
187
-
188
168
### function calls
189
169
190
170
``` xml
191
-
192
171
<Label text =" {{ someMethod(p1,p2,...,pN) }}" textWrap =" true" />
193
-
194
172
```
195
173
196
- ---
197
-
198
174
### comparison operators
199
175
200
176
``` xml
201
-
202
177
<Label text =" {{ property1 > property2 }}" textWrap =" true" />
203
-
204
178
```
205
179
206
180
Other supported operators are: ` < ` , ` <= ` , ` >= ` , ` == ` , ` != ` , ` === ` , ` !== ` .
207
181
208
- ---
209
-
210
182
:::tip Note
211
183
Special characters need to be escaped as follows:
212
184
213
- - double quotes(` " ` ) => ` " `
214
- - single quote(` ' ` ) => ` ' `
215
- - less than(` < ` ) => ` < `
216
- - greater than(` > ` ) => ` > `
217
- - ampersand(` & ` ) => ` & `
185
+ - double quotes: ` " ` &rightarrow ; ` " `
186
+ - single quote: ` ' ` &rightarrow ; ` ' `
187
+ - less than: ` < ` &rightarrow ; ` < `
188
+ - greater than: ` > ` &rightarrow ; ` > `
189
+ - ampersand: ` & ` &rightarrow ; ` & `
190
+
191
+ :::
218
192
219
193
## Using data converters
220
194
@@ -223,59 +197,53 @@ Often data within the Model is stored in a way that is optimized for best perfor
223
197
<!-- TODO: Add SB+Preview -->
224
198
225
199
``` xml
226
-
227
- <StackLayout class =" p-20 bg" >
228
-
229
- <Label text =" {{ date | dateConverter('dd-mm-yyyy') }}" textWrap =" true" />
230
- <Label text =" {{ name | toUpperCaseConverter }}" textWrap =" true" />
231
- <Label text =" {{ title | toTitle }}" textWrap =" true" />
232
-
233
- </StackLayout >
234
-
200
+ <StackLayout class =" p-20 bg" >
201
+ <Label text =" {{ date | dateConverter('dd-mm-yyyy') }}" textWrap =" true" />
202
+ <Label text =" {{ name | toUpperCaseConverter }}" textWrap =" true" />
203
+ <Label text =" {{ title | toTitle }}" textWrap =" true" />
204
+ </StackLayout >
235
205
```
236
206
237
207
``` ts
238
208
export class HelloWorldModel extends Observable {
239
-
240
- name = " nandee"
241
- title = " hello world!"
209
+ name = ' nandee'
210
+ title = ' hello world!'
242
211
date = Date .now () // number
243
212
dateConverter = this .formatDate ()
244
213
toUpperCaseConverter = this .toUpperCase ()
245
214
toTitle = this .convertToTitle ()
246
215
247
- ...
248
-
249
- formatDate() {
216
+ formatDate() {
250
217
return {
251
218
toView(value : number , format : string ) {
252
-
253
219
const date = new Date (value )
254
- const day = date .getDate ().toString ().padStart (2 , " 0 " )
255
- const month = (date .getMonth () + 1 ).toString ().padStart (2 , " 0 " ) // months are zero based in JS.
220
+ const day = date .getDate ().toString ().padStart (2 , ' 0 ' )
221
+ const month = (date .getMonth () + 1 ).toString ().padStart (2 , ' 0 ' ) // months are zero based in JS.
256
222
const year = date .getFullYear ().toString ()
257
223
258
- return format .replace (" dd" , day )
259
- .replace (" mm" , month )
260
- .replace (" yyyy" , year )
261
- }
224
+ return format
225
+ .replace (' dd' , day )
226
+ .replace (' mm' , month )
227
+ .replace (' yyyy' , year )
228
+ },
262
229
}
263
230
}
264
231
265
- toUpperCase(){
232
+ toUpperCase() {
266
233
return {
267
- toView(value : string ){
234
+ toView(value : string ) {
268
235
return value .toUpperCase ()
269
- }
236
+ },
270
237
}
271
238
}
272
239
273
- convertToTitle(){
240
+ convertToTitle() {
274
241
return {
275
- toView(str : string ){
276
- return str .replace (/ (^ | \s )\S / g , function (t ) { return t .toUpperCase () });
277
-
278
- }
242
+ toView(str : string ) {
243
+ return str .replace (/ (^ | \s )\S / g , function (t ) {
244
+ return t .toUpperCase ()
245
+ })
246
+ },
279
247
}
280
248
}
281
249
}
0 commit comments