Docs

Everything You Need to Know

Models

API

Model

$.Model(options)

This is a factor that creates a model object for you based on the options you provide. It takes two arguments, the data to encapsule in the model, and a handle to use as its identifier. The model uses the handle to inform the system when it has changed. Mediators listen for this handle and react when it is dispatched.

Models can hold either an object of key-value pairs, or a array of objects. Depending on the contents, different methods will work. Array methods will not work with an object model and object methods will not work with a array model. However, some methods are share by both models:.

After putting your data in a model, you can dispose of it if you want to free up memory:

// Create a new model:
var MyModel = $.Model(myData, 'mydata-handle');
// Set the data for garbage collection:
myData = null;

Models can hold two kinds of data: a single object of properties and values, or an array of objects. Dependeing on which of these two a model holds, it exposes different methods for you to use. We'll first look at the model methods of a object, then at those for an array.

Model of Single Object Data

When a model holds a single object of properties and values, the model exposes the following methods:

get

get(property?)

This method lets you get the value of the provided property if it exists on the object stored in the model. If no property is provided, it returns the comple object of data.

// Get the value of `name`:
var name = myModel.get('name');

// Get all the model's data:
var data = myModel.get();

set

set(property, data)

This method lets you set a property and value on the model's data. If the property already exists, its value will be updated to that provided by this method. If the property does not currently exist on the model's data, it will be added.

// Update the model's name property:
myModel.set('name', 'John Doe');

// Add a new property to the model's data:
myModel.set('age', 32);

remove

remove(property)

This method lets you remove a property from the model's data.

// Remove `age` from the model:
myModel.remove('age');
myModel.get('age') // returns undefined

merge

merge(object)

This method lets you merge an object into the model's data. If any of the properties of the object being merged into the model already exist on the model, they will be replaced with those of the merged object. And any properties unique to the merged object will be added to the model.

// Merge an object into the model:
var person = {
  name: 'Joe Bodoni',
  age: 32
};
var personModel = $.Model(person);
var obj = {
  age: 40,
  job: 'rocket scientist',
  address: '123 Lazy Lane, Clownville, Bozowania'
};
// Merge the object into the model:
personModel.merge(obj);
// personModel now:
{
  name: 'Joe Bodoni',
  age: 40,
  job: 'rocket scientist',
  address: '123 Lazy Lane, Clownville, Bozowania'
}

mixin

mixin

This method lets you extend a model with the properties of the provided object. Unlike mixin, if the properties of the object already exist on the model, they will not be replaced. Only properties that are not currently on the model will be added.

In the following example, notice how the final model only received properties that were new after the mixin.

// Mixin an object into the model:
var person = {
  name: 'Joe Bodoni',
  age: 32,
  hobby: 'sleeping'
};
var personModel = $.Model(person);
var obj = {
  age: 40,
  hobby: 'eating',
  job: 'rocket scientist',
  address: '123 Lazy Lane, Clownville, Bozowania'
};
// Mixin the object into the model:
personModel.mixin(obj);
// personModel now:
{
  name: 'Joe Bodoni',
  age: 32,
  hobby: 'sleeping'
  job: 'rocket scientist',
  address: '123 Lazy Lane, Clownville, Bozowania'
}

Model of Array of Objects

When a model holds an array of objects, the model exposes the following methods:

get

get()

This method lets you get all of the model's data. Since this is an array of objects, that is what you will get.

// Get the model's data:
var data = myModel.get();

getPropAt

getPropAt(property, position)

This method lets you get the value of a property at the specified position in the model's array. It takes two arguments: the property and position in the array.

// Get the property at position:
var name = personModel.getPropAt('name', 11);
console.log('The name is: ' + name);

If you use a negative number as a position, that will count back from the end of the collection. So, a position of -1 would be the last item in the collection, -2 would be the next to last, etc.

setPropAt

setPropAt(property, value, position)

This method lets you set the value of a property at the specified position in the model's array. It takes three arguments: the property, the value for the property, and the position in the model's array.

// Set the value of a property:
personMode.setPropAt('name', 'John Doe', 21);

If you use a negative number as a position, that will count back from the end of the collection. So, a position of -1 would be the last item in the collection, -2 would be the next to last, etc.

push

push(data)

This method lets you push data onto the model's data. This works like the Array.push method.

// Push some data onto the model:
myModel.push({name: 'Joe', age: 22});

pop

pop()

This method lets you pop the last item off of the model, just like Array.pop.

// Pop the last item from the model:
var lastPerson = peopleModel.pop();
console.log(lastPerson.name);

unshift

unshift(data)

This method lets you insert data to the beginning of a model, just like Array.unshift.

// Insert data at the start of the model:
peopleModel.unshift({
  name: 'Susan',
  age: 25
});

shift

shift()

This method lets you

// Pop the first item from the model:
var firstPerson

slice

slice(start, end)

This method lets you get a slice of the model's data. This works the same as Array.slice by returning a new array and does not affect the integrity of the model's data. Note: the start and end value are zero-based.

// Get a slice of the model:
var tenPeople = peopleModel.slice(0, 9);
peopleView.render(tenPeople);

splice

splice(start, end, data)

This method lets you splice your model's data. This works the same as Array.splice, so it does directly manipulate the model's data. Splicing allows you to insert new content into the array, remove a chunk of the array or replace a range of the array with new data. Note: the start and end value are zero-based.

// Get a chuck of the model:
var chuck = productsModel.splice(9, 19, newProducts);

If you have multiple items you want to slice into the model, do not try to do so as an array, as the array itself will be inserted. Instead provides the items individual as arguments after the end position separated by commas.

insert

insert(position, data)

Like splice, this method lets you directly insert data into the model. You provide the position to insert at and the data to insert. Note: the position value is zero-based.

// Insert data into model:
myProducts.insert(20, {name: 'Sam', age 40});

If you have multiple items you want to insert into the model, do not try to do so as an array, as the array itself will be inserted. Instead provides the items individual as arguments after the insert position separated by commas.

pluck

pluck(property)

This method lets you pluck all the values of a property from the model. You might, for example, want to get all the prices of a model of products, or the last names of all costumers in a model. Just provide the property you want and this method will return the values as an array.

// Get prices from model:
var prices = prodoctsModel.pluck('price');
prices.sort().reverse();
pricesView.render(prices);

find

find(callback)

This method works the same as Array.find. Its callback can perform any kind of operation on any property to determine whether to return the object or not. This is similar to the model's getPropEquals, but more versatile. If you need to performs some complicated test to determine whether to get the object by a property, this is the version to use.

// Find a model's object by last name:
var john = peopleModel.find(function(person) {
  return person.firstName === 'John' && person.last !== 'Thompson';
});

indexOf

indexOf(value)

This method works the same as Array.indexOf. As such, it is only works if the model's data is an array so simple values. If the model holds an array of objects, then use findIndex go get the object's index value.

// Get the index of a value in the model:
var index = namesModel.indexOf('Joe');

findIndex

findIndex(callback)

This method works the same as Array.findIndex. You provide a callback to test the wether to return the index of an object.

// Get index of object in model:
var index = peopleModel.findIndex(function(person) {
  return person.firstName === 'Joe' && person.lastName !== 'Macaroni';
});

forEach

forEach(callback)

This method works the same as Array.forEach. It allows you to run a callback against every item in the model. You can also directly manipulate the data of that iteration, changing the content of the model.

// Change all last names to uppercase:
peopleModel.forEach(function(person) {
  person.lastName.toUpperCase();
});

filter

filter(callback)

This method works the same as Array.filter. It allows you to run a callback against every item in the array and return a new array based on the results.

// Filter people by age:
var youngPeople = peopleModel.filter(function(person) {
  return person.age < 30;
});
youngPeopleView.render(youngPeople);

map

map(callback)

This method works the same as Array.map. It allows you to run a function against every item of the array and returns a new array based on the outcome of that callback. Unlike forEach, map does not let you affect the model's data directly but instead returns a new array with those changes.

// Update prices with new tax rate:
var updatedPrices = productsModel.map(function(product) {
  return updateWithNewTax(product.price);
});
pricesView.render(updatedPrices);

reverse

reverse()

This method works the same as Array.reverse. However, it also works with arrays of objects.

// Reverse the model's data:
pricesModel.reverse();
// Render the new price order
// in view bound to this model:
pricesView.render();

sort

sort(callback)

This method works the same as Array.sort. You must provide a callback to test the values of the model's objects for the sort order.

// Sort last names in ascending order:
peopleModel.sort(function(person1, person2) {
  if (person1.lastName.toLowerCase() < person2.lastName.toLowerCase()) {
    return -1;
  } else if(person1.lastName.toLowerCase() > person2.lastName.toLowerCase()) {
    return 1;
  }
});
// Re-render view bound to this model:
peopleView.render();

orderBy

orderBy(property1, property2?)

This method lets you sort a model based on various sort criteria. For example, you could sort a model by first name, last name and age. The default sort order is ascending, but you can change the sort order to descending by prefixing a property with a hyphen.

// Order model by first and last names:
peopleModel.orderBy(firstName, lastName);
// Re-render view bound to this model:
peopleView.render();
// Order model by age with oldest first:
peopleModel.orderBy(-age);
peopleView.render();

concat

concat(newArray)

This method works the same as Array.concat. When you concat an array of new objects to a model, the content of the array is added to the mode, not the array itself. This is useful if you do a non-destructive operation on an array and got a new copy back which you want to add to a model.

// Concat new data to the model:
var newPeople = [
  {firstName: 'Homer', lastName: 'Simpson'},
  {firstName: 'Marge', lastName: 'Simpson'},
  {firstName: 'Bart', lastName: 'Simpson'},
  {firstName: 'Lisa', lastName: 'Simpson'},
];
peopleModel.concat(newPeople);
// Re-render view bound to this model:
peopleView.render();

mixin

mixin(newArray)

Like mixin for object property, this method will mixin and array of objects to the model. If their are any duplicates, they will be eliminated.

// Mixin new data to model:
productsModel.mixin(newItems);
// Re-render view bound to this model:
productsView.render();

unique

unique()

This method will remove any publicates from the model. This is useful where the user might have made multiple entries of the same thing without realizing it.

// Remove duplicates from model:
productsModel.unique();
// Re-render view bound to this model:
productsView.render();

eq

eq(position)

This method lets you get an object from the model based on its position. This is a zero-based value. You could get the position using findIndex or whatever means you might have.

// Get the tenth person from model:
var tenthPerson = peopleModel.eq(9);

size

size()

This method returns the number of objects in a model.

// Get the number of products:
var number = cartModel.size();
alert('You have ' + number + ' items in your cart.');

Medhods Shared by Objects and Arrays

The following methods are shared by models of objects and arrays.

on

on(event, callback)

This method works like attaching events to a DOM element. You can create custom events that make sense for what you app needs to do. You can also regester multiple callbacks to the same event, just like DOM element events. You can use model events to do things such as:

  1. Update a view after manipulating the model.
  2. Validate the model's data.
  3. Persist the model's data locally.
  4. Push the model's data to a remote domain.

You may have other uses for model events as well.

// Add an event to a model:
myModel.on('update', function() {
  console.dir(myModel.get());
});
// Add another `update` event to the model:
myModel.on('update', function() {
  alert('Just updated the model!');
});

// If we trigger `update` on myModel,
// both of the above will execute.

trigger

trigger(event, data?)

When a model has an event registered, you can use `trigger` to make the model's event handler execute. You can also pass along some data, which will be available as its argument in the event callback.

// Trigger and event on a model:
myModel.trigger('update');
// Register another event:
myModel.on('announce', function(data) {
  console.log(data);
});
// Trigger the `announce` event:
myModel.trigger('This is an announcement.');
// The model returns 'This is an announcemnt.'

off

off(event)

This method let you remove an event from a model. Just provide the event name. If there are multiple callbacks regesterd on the event, all of them will be removed.

// Remove a model event:
myModel.off('announce');
// Now this does nothing:
myModel.trigger('announce');

events

events()

This method returns all events and their callbacks currently registered on a model.

// Get all events on the model:
var events = myModel.events();

removeEventCallback

removeEventCallback(event, position)

Just as you can remove an event from a model, you can more specifically remove a callback from a model's event. The position is zero-based. A model event's callbacks are stored as an array. This method removes a callback based on its position in that array. If a model's event has only one event, using this is unnecessary. In that case it would be better to use myModel.off(event).

// Remove the second callback:
myModel.on('update', function() {
  console.dir(myModel.get());
});
// Add another `update` event to the model:
myModel.on('update', function() {
  alert('Just updated the model!');
});
// Trigger `update`.
// Both callbacks will fire:
myModel.trigger('update');
// Remove the last callback:
myModel.removeEventCallback('update', 1);
// This time only the first callback gets fired:
myModel.trigger('update');

stop

stop()

Rather than deleting an event from a model, you can instead simply `stop` it. This prevents the event from executing until it is started again.

// Stop a model's events:
myModel.stop();
// This will not do anything:
myModel.trigger('update', 'Something here.');

start

start()

If you needed to stop a model's events for some reason, you can use this method to start the model's events again.

// Restart a model's events:
myModel.stop();
// This does nothing:
myModel.trigger('announce', 'A message here.');
// Restart the model:
myModel.start();
// This now works:
myModel.trigger('annoucne', 'A new message this time.');

isStopped

isStopped()

This method lets you test whether a model's events have been stopped or not. It returns a boolean.

// Test if the model is stopped:
if (myModel.isStopped()) {
  myModel.start();
  myModel.trigger('update');
}

purge

purge()

This method will delete all data from the model, leaving only and empty object: {}. After purging a model, myModel.get() will return {}.

// Delete all data from an object in a model:
myModel.purge();
// Check what the model holds:
myModel.get();
// returns {}

replace

replace(data, renderView)

This method allows you to quickly replace all the data in the model with other data. This is so that you can do some complicated operations on the data before updating the model. By default using this method does not cause a view to render. However, if you pass any secondary boolean true argument (renderView), the bound view will be rendered with the changes.

// Replace model data, do not render view:
myModel.replace(newData);

// Replace model data and render view:
myModel.replace(newData, true);