NativeScript Core Modules compatibility package for building native iOS and Android apps using JavaScript and CSS
—
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.
Core observable class providing property change notifications and event handling for reactive data management.
/**
* Base observable class for reactive data objects
*/
class Observable {
constructor(obj?: any);
// Property access
get(name: string): any;
set(name: string, value: any): void;
setProperty(name: string, value: any): void;
// Event handling
on(eventName: string, callback: (data: EventData) => void): void;
off(eventName: string, callback?: (data: EventData) => void): void;
notify(data: EventData): void;
notifyPropertyChange(propertyName: string, value: any, oldValue?: any): void;
// Utility methods
hasListeners(eventName: string): boolean;
addEventListener(arg: string | EventData, callback?: Function): void;
removeEventListener(arg: string | EventData, callback?: Function): void;
// Static helper
static propertyChangeEvent: "propertyChange";
}Usage Examples:
import { Observable } from "tns-core-modules";
// Create observable object
const user = new Observable({
name: "John Doe",
age: 30,
email: "john@example.com"
});
// Listen for property changes
user.on(Observable.propertyChangeEvent, (args) => {
console.log(`Property ${args.propertyName} changed from ${args.oldValue} to ${args.value}`);
});
// Update properties (triggers change events)
user.set("name", "Jane Doe");
user.set("age", 25);
// Direct property access
const currentName = user.get("name");
// Batch updates
user.set("name", "Bob Smith");
user.set("email", "bob@example.com");Observable array implementation providing standard array functionality with change notifications for reactive collection management.
/**
* Observable array with change notifications
*/
class ObservableArray<T> extends Array<T> {
constructor(...items: T[]);
// Standard array methods (with notifications)
push(...items: T[]): number;
pop(): T | undefined;
shift(): T | undefined;
unshift(...items: T[]): number;
splice(start: number, deleteCount?: number, ...items: T[]): T[];
reverse(): T[];
sort(compareFn?: (a: T, b: T) => number): this;
// Observable functionality
on(eventName: string, callback: (data: ChangedData<T>) => void): void;
off(eventName: string, callback?: (data: ChangedData<T>) => void): void;
notify(data: EventData): void;
// Collection-specific methods
getItem(index: number): T;
setItem(index: number, value: T): void;
// Static event constants
static changeEvent: "change";
}Usage Examples:
import { ObservableArray, ChangeType } from "tns-core-modules";
// Create observable array
const items = new ObservableArray<string>("Apple", "Banana", "Orange");
// Listen for changes
items.on(ObservableArray.changeEvent, (args) => {
console.log(`Array changed: ${args.action}`);
console.log(`Index: ${args.index}, Items: ${args.addedCount}`);
});
// Modify array (triggers change events)
items.push("Grape"); // Triggers add event
items.splice(1, 1, "Mango"); // Triggers delete + add events
const removed = items.pop(); // Triggers delete event
// Array operations
items.sort();
items.reverse();
// Direct access
const firstItem = items.getItem(0);
items.setItem(1, "Pineapple");Event data structures for observable change notifications and property updates.
/**
* Base event data interface
*/
interface EventData {
eventName: string;
object: any;
}
/**
* Property change event data
*/
interface PropertyChangeData extends EventData {
propertyName: string;
value: any;
oldValue: any;
object: Observable;
}
/**
* Array change event data
*/
interface ChangedData<T> extends EventData {
action: ChangeType;
index: number;
removed: T[];
addedCount: number;
object: ObservableArray<T>;
}
/**
* Change type enumeration for array operations
*/
enum ChangeType {
Add = "add",
Delete = "delete",
Update = "update",
Splice = "splice"
}High-performance array implementation for large datasets with virtualization support.
/**
* Virtual array for handling large datasets efficiently
*/
class VirtualArray<T> extends ObservableArray<T> {
constructor(length?: number);
// Virtual array specific properties
length: number;
// Data loading
load(index: number, count?: number): T[];
loadAsync(index: number, count?: number): Promise<T[]>;
// Item management
getItem(index: number): T;
setItem(index: number, item: T): void;
requestItemAt(index: number): T;
// Change detection
change(data: ChangedData<T>): void;
}Utility functions and classes for advanced data binding scenarios and view model management.
/**
* Binding context for data binding operations
*/
interface BindingContext {
$parent?: any;
$parents?: any[];
$root?: any;
$index?: number;
$value?: any;
}
/**
* Two-way binding helper functions
*/
namespace Binding {
function bind(target: any, targetProperty: string, source: Observable, sourceProperty: string): void;
function unbind(target: any, targetProperty: string): void;
// Binding expressions
function getBindingMemberInfo(name: string, source: any): any;
function prepareCSS(source: string): string;
}
/**
* Property change listener utility
*/
class WeakRef<T> {
constructor(obj: T);
get(): T | undefined;
clear(): void;
}Advanced Data Binding Examples:
import { Observable, ObservableArray, Page, ListView, Label } from "tns-core-modules";
// View model with nested observables
class UserViewModel extends Observable {
private _users: ObservableArray<User>;
private _selectedUser: User;
constructor() {
super();
this._users = new ObservableArray<User>();
this.loadUsers();
}
get users(): ObservableArray<User> {
return this._users;
}
get selectedUser(): User {
return this._selectedUser;
}
set selectedUser(value: User) {
if (this._selectedUser !== value) {
this._selectedUser = value;
this.notifyPropertyChange("selectedUser", value);
}
}
addUser(user: User): void {
this._users.push(user);
}
removeUser(index: number): void {
this._users.splice(index, 1);
}
private loadUsers(): void {
// Simulate loading users
this._users.push(
new User("John", "john@example.com"),
new User("Jane", "jane@example.com")
);
}
}
class User extends Observable {
constructor(public name: string, public email: string) {
super();
}
}
// Page with data binding
export function createPage() {
const page = new Page();
const viewModel = new UserViewModel();
// Set binding context
page.bindingContext = viewModel;
// Create UI with data binding
const listView = new ListView();
listView.bind({
sourceProperty: "users",
targetProperty: "items"
});
page.content = listView;
return page;
}Install with Tessl CLI
npx tessl i tessl/npm-tns-core-modules