or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application.mddata-binding.mdfile-system.mdhttp-client.mdimage-handling.mdindex.mdplatform-utils.mdui-components.md

data-binding.mddocs/

0

# Data Binding and Observables

1

2

Reactive data handling system supporting two-way data binding, change notifications, and observable collections. The data binding system enables automatic UI updates when data changes and supports complex data relationships.

3

4

## Capabilities

5

6

### Observable Class

7

8

Core observable class providing property change notifications and event handling for reactive data management.

9

10

```typescript { .api }

11

/**

12

* Base observable class for reactive data objects

13

*/

14

class Observable {

15

constructor(obj?: any);

16

17

// Property access

18

get(name: string): any;

19

set(name: string, value: any): void;

20

setProperty(name: string, value: any): void;

21

22

// Event handling

23

on(eventName: string, callback: (data: EventData) => void): void;

24

off(eventName: string, callback?: (data: EventData) => void): void;

25

notify(data: EventData): void;

26

notifyPropertyChange(propertyName: string, value: any, oldValue?: any): void;

27

28

// Utility methods

29

hasListeners(eventName: string): boolean;

30

addEventListener(arg: string | EventData, callback?: Function): void;

31

removeEventListener(arg: string | EventData, callback?: Function): void;

32

33

// Static helper

34

static propertyChangeEvent: "propertyChange";

35

}

36

```

37

38

**Usage Examples:**

39

40

```typescript

41

import { Observable } from "tns-core-modules";

42

43

// Create observable object

44

const user = new Observable({

45

name: "John Doe",

46

age: 30,

47

email: "john@example.com"

48

});

49

50

// Listen for property changes

51

user.on(Observable.propertyChangeEvent, (args) => {

52

console.log(`Property ${args.propertyName} changed from ${args.oldValue} to ${args.value}`);

53

});

54

55

// Update properties (triggers change events)

56

user.set("name", "Jane Doe");

57

user.set("age", 25);

58

59

// Direct property access

60

const currentName = user.get("name");

61

62

// Batch updates

63

user.set("name", "Bob Smith");

64

user.set("email", "bob@example.com");

65

```

66

67

### Observable Array

68

69

Observable array implementation providing standard array functionality with change notifications for reactive collection management.

70

71

```typescript { .api }

72

/**

73

* Observable array with change notifications

74

*/

75

class ObservableArray<T> extends Array<T> {

76

constructor(...items: T[]);

77

78

// Standard array methods (with notifications)

79

push(...items: T[]): number;

80

pop(): T | undefined;

81

shift(): T | undefined;

82

unshift(...items: T[]): number;

83

splice(start: number, deleteCount?: number, ...items: T[]): T[];

84

reverse(): T[];

85

sort(compareFn?: (a: T, b: T) => number): this;

86

87

// Observable functionality

88

on(eventName: string, callback: (data: ChangedData<T>) => void): void;

89

off(eventName: string, callback?: (data: ChangedData<T>) => void): void;

90

notify(data: EventData): void;

91

92

// Collection-specific methods

93

getItem(index: number): T;

94

setItem(index: number, value: T): void;

95

96

// Static event constants

97

static changeEvent: "change";

98

}

99

```

100

101

**Usage Examples:**

102

103

```typescript

104

import { ObservableArray, ChangeType } from "tns-core-modules";

105

106

// Create observable array

107

const items = new ObservableArray<string>("Apple", "Banana", "Orange");

108

109

// Listen for changes

110

items.on(ObservableArray.changeEvent, (args) => {

111

console.log(`Array changed: ${args.action}`);

112

console.log(`Index: ${args.index}, Items: ${args.addedCount}`);

113

});

114

115

// Modify array (triggers change events)

116

items.push("Grape"); // Triggers add event

117

items.splice(1, 1, "Mango"); // Triggers delete + add events

118

const removed = items.pop(); // Triggers delete event

119

120

// Array operations

121

items.sort();

122

items.reverse();

123

124

// Direct access

125

const firstItem = items.getItem(0);

126

items.setItem(1, "Pineapple");

127

```

128

129

### Event Data Interfaces

130

131

Event data structures for observable change notifications and property updates.

132

133

```typescript { .api }

134

/**

135

* Base event data interface

136

*/

137

interface EventData {

138

eventName: string;

139

object: any;

140

}

141

142

/**

143

* Property change event data

144

*/

145

interface PropertyChangeData extends EventData {

146

propertyName: string;

147

value: any;

148

oldValue: any;

149

object: Observable;

150

}

151

152

/**

153

* Array change event data

154

*/

155

interface ChangedData<T> extends EventData {

156

action: ChangeType;

157

index: number;

158

removed: T[];

159

addedCount: number;

160

object: ObservableArray<T>;

161

}

162

163

/**

164

* Change type enumeration for array operations

165

*/

166

enum ChangeType {

167

Add = "add",

168

Delete = "delete",

169

Update = "update",

170

Splice = "splice"

171

}

172

```

173

174

### Virtual Array

175

176

High-performance array implementation for large datasets with virtualization support.

177

178

```typescript { .api }

179

/**

180

* Virtual array for handling large datasets efficiently

181

*/

182

class VirtualArray<T> extends ObservableArray<T> {

183

constructor(length?: number);

184

185

// Virtual array specific properties

186

length: number;

187

188

// Data loading

189

load(index: number, count?: number): T[];

190

loadAsync(index: number, count?: number): Promise<T[]>;

191

192

// Item management

193

getItem(index: number): T;

194

setItem(index: number, item: T): void;

195

requestItemAt(index: number): T;

196

197

// Change detection

198

change(data: ChangedData<T>): void;

199

}

200

```

201

202

### Data Binding Utilities

203

204

Utility functions and classes for advanced data binding scenarios and view model management.

205

206

```typescript { .api }

207

/**

208

* Binding context for data binding operations

209

*/

210

interface BindingContext {

211

$parent?: any;

212

$parents?: any[];

213

$root?: any;

214

$index?: number;

215

$value?: any;

216

}

217

218

/**

219

* Two-way binding helper functions

220

*/

221

namespace Binding {

222

function bind(target: any, targetProperty: string, source: Observable, sourceProperty: string): void;

223

function unbind(target: any, targetProperty: string): void;

224

225

// Binding expressions

226

function getBindingMemberInfo(name: string, source: any): any;

227

function prepareCSS(source: string): string;

228

}

229

230

/**

231

* Property change listener utility

232

*/

233

class WeakRef<T> {

234

constructor(obj: T);

235

get(): T | undefined;

236

clear(): void;

237

}

238

```

239

240

**Advanced Data Binding Examples:**

241

242

```typescript

243

import { Observable, ObservableArray, Page, ListView, Label } from "tns-core-modules";

244

245

// View model with nested observables

246

class UserViewModel extends Observable {

247

private _users: ObservableArray<User>;

248

private _selectedUser: User;

249

250

constructor() {

251

super();

252

this._users = new ObservableArray<User>();

253

this.loadUsers();

254

}

255

256

get users(): ObservableArray<User> {

257

return this._users;

258

}

259

260

get selectedUser(): User {

261

return this._selectedUser;

262

}

263

264

set selectedUser(value: User) {

265

if (this._selectedUser !== value) {

266

this._selectedUser = value;

267

this.notifyPropertyChange("selectedUser", value);

268

}

269

}

270

271

addUser(user: User): void {

272

this._users.push(user);

273

}

274

275

removeUser(index: number): void {

276

this._users.splice(index, 1);

277

}

278

279

private loadUsers(): void {

280

// Simulate loading users

281

this._users.push(

282

new User("John", "john@example.com"),

283

new User("Jane", "jane@example.com")

284

);

285

}

286

}

287

288

class User extends Observable {

289

constructor(public name: string, public email: string) {

290

super();

291

}

292

}

293

294

// Page with data binding

295

export function createPage() {

296

const page = new Page();

297

const viewModel = new UserViewModel();

298

299

// Set binding context

300

page.bindingContext = viewModel;

301

302

// Create UI with data binding

303

const listView = new ListView();

304

listView.bind({

305

sourceProperty: "users",

306

targetProperty: "items"

307

});

308

309

page.content = listView;

310

return page;

311

}

312

```