Model Entities and JavaScript Types

All model types have a corresponding JavaScript "class" of the same name. In other words, the ExoWeb model generates code on the client based on its meta model. This makes application code more seamless. Also, the meta model is cleaner in that property types can be of any JavaScript type, which includes JavaScript intrinsic types or model type classes.

Object Identity

All entities have a id property, meta.id , that uniquely identifies the instance. For consistency and simplicity all ids are strings. If the server-side model uses types other than strings that is fine because the ExoWeb service translates those types to and from strings on the client to maintain that abstraction.

Identity is shared across a family of classes. For example, consider the situation where there is a base class, Animal with subclasses Dog and Cat then Animal.meta.get(aDogId) === Dog.meta.get(aDogId) is true.

For objects that are not yet persisted, ExoWeb will generate a client-only ID that will be used until the object has been persisted. These ids are typically in the format: "+c000" where 000 is a unique integer. After the object is persisted its meta.id property will be updated. However, the object can still be referenced using its old ID for the lifetime of the page to help simplify application code.

Object Construction and Lifecycle

Objects are always constructed using the standard Javascript constructor for the entity type. There are several ways the the constructor can be called:

Constructors Description
new Widget() Creates a new object with its default state.
new Widget({prop1: val1, prop2: val2, propN: valN }) Creates a new object with its default state and then sets its properties based on the argument.
new Widget(id) Creates an object that will be bound to the persisted state identified by id . This object may not yet be loaded. See Browser/Server Communication for information on loading.
new Widget(id, {prop1: val1, prop2: val2, propN: valN }) Creates an object that will be bound to the persisted state identified by id and sets its properties based on the arguments. This is useful if you have retrieved some data from a web service call and wish to pre-populate objects with this data without having to perform loading.

Object Pooling

The object construction process checks the object pool and will return an existing object if one already exists. This means that the following relationship is always true: (new Dog(id)) === (new Dog(id)) . In that example, the reference returned by the constructor in both cases is to the same instance.

For an array of all instances that are in the object pool, invoke the known() method on the type's meta object: Dog.meta.known()

Inheritance

Single inheritance among entity classes is fully supported and all model classes derive from ExoWeb.Model.Entity . Inheritance is exposed naturally though using standard javascript prototype-based inheritance. This means that the instanceof operator works as expected.

Extending Types with $extend()

Using the $extend function, it is possible to augment the built-in behavior of a type, which can be set up before the type exists.

function $extend(typeInfo, callback)

typeInfo The string type name, or an array of string type names.
callback A JavaScript function to be executed when the type(s) are available. Note: If a single type name is used the argument to the callback method will be the JavaScript constructor function. If an array of names is used then the argument(s) will be the constructor functions, in the order that they were listed.


Example:
	$extend("Person", function(type) {
		// NOTE:  The "type" variable refers to the "Person" JavaScript constructor function.  To get the model type, use the "meta" attribute.
		type.meta.addProperty({ /* property information */);
	});
	
	$extend(["Person", "Place"], function(person, place) {
		person.meta.addProperty({ /* property information */);
		place.meta.addProperty({ /* property information */);
	});

Property Paths

Property paths must, with one exception, always start with a "this" reference for instance properties or the containing class name for static properties. The exception to this rule is when a property looked up via type.property("path").

Example:
	this.StartDate

Property paths can include type directives. This directives are used to determine which class to look for the property on which is needed in some cases where inheritance is used.

Example:
	this.Contacts<Employee>.HireDate

The will cause the contact to be treated as if it was of type "Employee", allowing you to access properties that are specific to an employee. In this case, this property is a list of mixed types so the type directive will also act as a filter and ignore events from objects that are not of that type.

Last edited Aug 12, 2010 at 5:05 PM by mattheyan, version 9

Comments

No comments yet.