or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

binding.mdcomponents.mdindex.mdobservables.mdperformance.mdtemplates.mdutils.md
tile.json

observables.mddocs/

0

# Observable System

1

2

Core reactive data binding system providing observable values, computed observables, and observable arrays for automatic UI synchronization. The observable system is the foundation of Knockout.js, enabling two-way data binding and automatic UI updates.

3

4

## Capabilities

5

6

### Observable Creation

7

8

Creates observable values that can be read, written, and subscribed to for change notifications.

9

10

```javascript { .api }

11

/**

12

* Creates an observable value

13

* @param initialValue - The initial value (optional)

14

* @returns Observable instance

15

*/

16

function observable<T>(initialValue?: T): Observable<T>;

17

18

/**

19

* Creates an observable array with array manipulation methods

20

* @param initialItems - Initial array items (optional)

21

* @returns ObservableArray instance

22

*/

23

function observableArray<T>(initialItems?: T[]): ObservableArray<T>;

24

```

25

26

**Usage Examples:**

27

28

```javascript

29

import ko from "knockout";

30

31

// Basic observable

32

const name = ko.observable("John");

33

console.log(name()); // "John"

34

name("Jane");

35

console.log(name()); // "Jane"

36

37

// Observable with no initial value

38

const age = ko.observable();

39

age(25);

40

41

// Observable array

42

const items = ko.observableArray(["apple", "banana"]);

43

items.push("orange");

44

console.log(items()); // ["apple", "banana", "orange"]

45

```

46

47

### Computed Observables

48

49

Creates computed observables that automatically recalculate when their dependencies change.

50

51

```javascript { .api }

52

/**

53

* Creates a computed observable that derives its value from other observables

54

* @param evaluator - Function that returns the computed value

55

* @param evaluatorTarget - Optional 'this' context for evaluator

56

* @param options - Optional configuration

57

* @returns Computed observable

58

*/

59

function computed<T>(evaluator: () => T): Computed<T>;

60

function computed<T>(evaluator: () => T, evaluatorTarget: any): Computed<T>;

61

function computed<T>(options: ComputedOptions<T>): Computed<T>;

62

63

/**

64

* Creates a pure computed observable with optimized behavior

65

* @param evaluator - Function that returns the computed value

66

* @returns PureComputed observable

67

*/

68

function pureComputed<T>(evaluator: () => T): PureComputed<T>;

69

function pureComputed<T>(options: ComputedOptions<T>): PureComputed<T>;

70

```

71

72

**Usage Examples:**

73

74

```javascript

75

import ko from "knockout";

76

77

const firstName = ko.observable("John");

78

const lastName = ko.observable("Doe");

79

80

// Basic computed

81

const fullName = ko.computed(() => {

82

return firstName() + " " + lastName();

83

});

84

85

// Computed with write function

86

const fullNameWritable = ko.computed({

87

read: () => firstName() + " " + lastName(),

88

write: (value) => {

89

const parts = value.split(" ");

90

firstName(parts[0] || "");

91

lastName(parts[1] || "");

92

}

93

});

94

95

// Pure computed (optimized for better performance)

96

const displayName = ko.pureComputed(() => {

97

return firstName() + " " + lastName();

98

});

99

```

100

101

### Observable Interface

102

103

Core interface for all observable types with read/write and subscription capabilities.

104

105

```typescript { .api }

106

interface Observable<T> {

107

/** Read the current value */

108

(): T;

109

/** Write a new value and return any for API consistency */

110

(value: T): any;

111

112

/** Subscribe to value changes */

113

subscribe(callback: (newValue: T) => void): Subscription;

114

subscribe(callback: (newValue: T) => void, target: any): Subscription;

115

subscribe(callback: (newValue: T) => void, target: any, event: string): Subscription;

116

117

/** Read value without creating a dependency */

118

peek(): T;

119

120

/** Manually notify subscribers that the value has changed */

121

valueHasMutated(): void;

122

123

/** Notify subscribers that the value is about to change */

124

valueWillMutate(): void;

125

126

/** Extend the observable with additional behavior */

127

extend(extenders: ExtenderOptions): Observable<T>;

128

129

/** Get the number of active subscriptions */

130

getSubscriptionsCount(): number;

131

}

132

133

interface Subscription {

134

/** Remove the subscription */

135

dispose(): void;

136

/** Remove subscription when DOM node is removed */

137

disposeWhenNodeIsRemoved(node: Node): void;

138

}

139

```

140

141

### Observable Array Interface

142

143

Extended observable interface for arrays with array manipulation methods.

144

145

```typescript { .api }

146

interface ObservableArray<T> extends Observable<T[]> {

147

// Standard array methods

148

/** Add items to the end of the array */

149

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

150

/** Remove and return the last item */

151

pop(): T | undefined;

152

/** Remove and return the first item */

153

shift(): T | undefined;

154

/** Add items to the beginning of the array */

155

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

156

/** Remove and insert items at specified position */

157

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

158

/** Get a portion of the array */

159

slice(start?: number, end?: number): T[];

160

/** Reverse the array in place */

161

reverse(): ObservableArray<T>;

162

/** Sort the array in place */

163

sort(compareFunction?: (a: T, b: T) => number): ObservableArray<T>;

164

165

// Knockout-specific methods

166

/** Get the index of an item */

167

indexOf(item: T): number;

168

/** Replace an item with another */

169

replace(oldItem: T, newItem: T): void;

170

/** Remove specific items and return them */

171

remove(item: T): T[];

172

remove(predicate: (item: T) => boolean): T[];

173

/** Remove all items or specific items */

174

removeAll(): T[];

175

removeAll(items: T[]): T[];

176

/** Mark items as destroyed (adds _destroy: true property) */

177

destroy(item: T): void;

178

destroy(predicate: (item: T) => boolean): void;

179

/** Mark all items as destroyed */

180

destroyAll(): void;

181

destroyAll(items: T[]): void;

182

183

// Non-mutating methods

184

/** Get a sorted copy of the array */

185

sorted(compareFunction?: (a: T, b: T) => number): T[];

186

/** Get a reversed copy of the array */

187

reversed(): T[];

188

}

189

```

190

191

### Computed Observable Interface

192

193

Extended observable interface for computed values with dependency tracking.

194

195

```typescript { .api }

196

interface Computed<T> extends Observable<T> {

197

/** Dispose the computed and clean up dependencies */

198

dispose(): void;

199

/** Check if the computed is currently active */

200

isActive(): boolean;

201

/** Get the number of dependencies */

202

getDependenciesCount(): number;

203

/** Get array of dependent observables */

204

getDependencies(): Observable<any>[];

205

}

206

207

interface PureComputed<T> extends Computed<T> {

208

// Pure computeds have the same interface but optimized behavior

209

}

210

211

interface ComputedOptions<T> {

212

/** Function to compute the value */

213

read?: () => T;

214

/** Function to handle writes (makes computed writable) */

215

write?: (value: T) => void;

216

/** Context for read/write functions */

217

owner?: any;

218

/** Whether this is a pure computed */

219

pure?: boolean;

220

/** Defer evaluation until first access */

221

deferEvaluation?: boolean;

222

/** Dispose when this DOM node is removed */

223

disposeWhenNodeIsRemoved?: Node;

224

/** Function that returns true when computed should be disposed */

225

disposeWhen?: () => boolean;

226

}

227

```

228

229

### Extenders

230

231

Observable extension system for adding additional behavior like throttling and rate limiting.

232

233

```javascript { .api }

234

const extenders: {

235

/** Throttle observable notifications */

236

throttle: (observable: Observable<any>, timeout: number) => Observable<any>;

237

/** Rate limit observable notifications */

238

rateLimit: (observable: Observable<any>, options: RateLimitOptions) => Observable<any>;

239

/** Defer observable notifications */

240

deferred: (observable: Observable<any>, value: true) => Observable<any>;

241

/** Control notification behavior */

242

notify: (observable: Observable<any>, value: "always" | any) => Observable<any>;

243

/** Track array changes for observable arrays */

244

trackArrayChanges: (observable: ObservableArray<any>, value: true) => ObservableArray<any>;

245

};

246

```

247

248

```typescript { .api }

249

interface RateLimitOptions {

250

timeout: number;

251

method?: "notifyAtFixedRate" | "notifyWhenChangesStop";

252

}

253

254

interface ExtenderOptions {

255

throttle?: number;

256

rateLimit?: number | RateLimitOptions;

257

deferred?: true;

258

notify?: "always" | any;

259

trackArrayChanges?: true;

260

}

261

```

262

263

**Usage Examples:**

264

265

```javascript

266

import ko from "knockout";

267

268

// Throttle updates

269

const throttledValue = ko.observable("").extend({ throttle: 500 });

270

271

// Rate limit updates

272

const rateLimitedValue = ko.observable("").extend({

273

rateLimit: { timeout: 500, method: "notifyWhenChangesStop" }

274

});

275

276

// Defer updates

277

const deferredValue = ko.observable("").extend({ deferred: true });

278

```

279

280

### Dependency Tracking

281

282

Control dependency tracking behavior in computed observables and subscriptions.

283

284

```javascript { .api }

285

/**

286

* Execute function without creating dependencies

287

* @param callback - Function to execute

288

* @param callbackTarget - Optional 'this' context

289

* @param callbackArgs - Optional arguments array

290

* @returns Result of callback

291

*/

292

function ignoreDependencies<T>(

293

callback: () => T,

294

callbackTarget?: any,

295

callbackArgs?: any[]

296

): T;

297

298

/**

299

* Information about current computed context

300

*/

301

const computedContext: {

302

/** Get number of dependencies in current context */

303

getDependenciesCount(): number;

304

/** Get array of dependencies in current context */

305

getDependencies(): Observable<any>[];

306

/** Check if this is the initial evaluation */

307

isInitial(): boolean;

308

/** Register a dependency in current context */

309

registerDependency(observable: Observable<any>): void;

310

};

311

```

312

313

**Usage Examples:**

314

315

```javascript

316

import ko from "knockout";

317

318

// Access current computed context inside a computed

319

const computed = ko.computed(() => {

320

const context = ko.computedContext;

321

console.log("Dependencies:", context.getDependenciesCount());

322

console.log("Is initial run:", context.isInitial());

323

return someValue();

324

});

325

326

// Execute code without dependency tracking

327

const result = ko.ignoreDependencies(() => {

328

// This won't create dependencies even inside a computed

329

return someObservable() + anotherObservable();

330

});

331

```

332

333

### Observable Utilities

334

335

Utility functions for working with observables and managing async observable patterns.

336

337

```javascript { .api }

338

/**

339

* Creates a promise that resolves when a predicate becomes true

340

* @param predicate - Function returning boolean or observable boolean

341

* @returns Promise that resolves when predicate is true

342

*/

343

function when<T>(predicate: () => T): Promise<T>;

344

345

/**

346

* Subscribe to a predicate with callback (alternative to promise)

347

* @param predicate - Function returning boolean or observable boolean

348

* @param callback - Callback called when predicate becomes true

349

* @returns Subscription that can be disposed

350

*/

351

function when<T>(predicate: () => T, callback: (value: T) => void): Subscription;

352

```

353

354

**Usage Examples:**

355

356

```javascript

357

import ko from "knockout";

358

359

const isReady = ko.observable(false);

360

const data = ko.observable(null);

361

362

// Promise-based usage

363

ko.when(() => isReady()).then(() => {

364

console.log("System is ready!");

365

});

366

367

// Callback-based usage

368

const subscription = ko.when(() => data(), (value) => {

369

console.log("Data received:", value);

370

});

371

372

// Wait for complex conditions

373

ko.when(() => {

374

return user.isLoaded() && permissions.isLoaded() && settings.isLoaded();

375

}).then(() => {

376

console.log("All data loaded, initializing app");

377

});

378

```

379

380

### Testing Functions

381

382

Type checking functions for observable objects.

383

384

```javascript { .api }

385

/**

386

* Test if object is an observable

387

* @param obj - Object to test

388

* @returns True if object is observable

389

*/

390

function isObservable(obj: any): boolean;

391

392

/**

393

* Test if object is an observable array

394

* @param obj - Object to test

395

* @returns True if object is observable array

396

*/

397

function isObservableArray(obj: any): boolean;

398

399

/**

400

* Test if object is a computed observable

401

* @param obj - Object to test

402

* @returns True if object is computed

403

*/

404

function isComputed(obj: any): boolean;

405

406

/**

407

* Test if object is a pure computed observable

408

* @param obj - Object to test

409

* @returns True if object is pure computed

410

*/

411

function isPureComputed(obj: any): boolean;

412

413

/**

414

* Test if object is subscribable

415

* @param obj - Object to test

416

* @returns True if object is subscribable

417

*/

418

function isSubscribable(obj: any): boolean;

419

420

/**

421

* Test if object is a writeable observable

422

* @param obj - Object to test

423

* @returns True if object is writeable observable

424

*/

425

function isWriteableObservable(obj: any): boolean;

426

427

/**

428

* Alternative spelling for isWriteableObservable

429

* @param obj - Object to test

430

* @returns True if object is writeable observable

431

*/

432

function isWritableObservable(obj: any): boolean;

433

```