mojo


See Also Application, models.Base, models.Collection, views.Base, views.List, views.Stack, router

This package comes pre-bundled with all the default Mojo plugins, including the views, models, template engine, and http router.

Installation

NPM:

npm install mojojs --save-exact

Browser:

First download https://raw.githubusercontent.com/mojo-js/mojo.js/master/build/mojo.min.js, then insert it in the <head /> of your document:

application

the application instance

application.views

the property set by the views plugin. See http://www.mojojs.com/docs/api/application#views for documentation.

mojo.application.models.register({
  main: MainView,
  confirmPopup: ComfirmPopupView,
});

application.paperclip

the property set by the template plugin.

var tpl = application.paperclip.template("hello {{name}}");
document.body.appendChild(tpl.bind({ name: "Jim Carrey" }).render());

application.models

the property set by the models plugin. See http://www.mojojs.com/docs/api/application#models for documentation.

mojo.application.models.register({
  person: PersonModel,
  people: PeopleCollection
});

models

The models namespace. Contains Base, Collection.

var people = new mojo.models.Collection([
  new mojo.models.Base({ name: "Johnny Depp"    }),
  new mojo.models.Base({ name: "Tom Cruise"     }),
  new mojo.models.Base({ name: "Angelina Jolie" })
]);

views

The views namespace. Contains Base, Stack, and List.

var baseView = mojo.views.Base();
var stackView = mojo.views.Stack();
var listView = mojo.views.List();


Application


Extends bindable.Object
See Also views.Base, models.Base, templates

Your Mojo application entry point. This module ties everything together, and allows other parts of your application to communicate with each other. This should be your only singleton.

Installation

npm install mojo-application --save-exact

Playground Example

Here's an example of how to use just about every property / method in the Application class.

Application(properties)

Your main application entry point.

  • properties - properties to set on the application
    • nodeFactory - (optional) the node factory to use for creating views. Automatically set depending on the platform.

Application.main

The pre-defined application instance. This is the default application when the application parameter is omitted from the View(properties[, application]), and Model(properties[, application]) classes. Useful if you want a global reference to an application.

plugins

The plugins to register when initializing the application. See playground example for usage.

nodeFactory

The node factory to use for rendering the DOM

use(plugins...)

initialize()

method to initialize the application. This method calls willInitialize, and didInitialize. it also emits an initialize event.

override willInitialize()

called immediately before initializing the application

override didInitialize()

called immediately after initializing the application

Events

  • initialize - emitted when the application initializes

Extended API

Below are a list of extensions to mojo applications.

views

Property added by views extension when registering to the application.

views.register(classesOrClassName[, class])

Registers a view class that's accessible anywhere in the application. This is especially useful when registering reusable components you might want to use in something like paperclip components.

  • classesOrClassName - classes, or class name
  • class - the class if className is provided

var Application = require("mojo-application@0.1.x"),
views = require("mojo-views@0.2.x");

var app = new Application();
app.use(views);
app.views.register("someViewName", views.Base);
app.views.register({
  someViewName: views.Base,
  someOtherView: views.Base.extend({
    paper: require("./someTemplate.pc")
  })
});

views.create(className, properties)

Creates a new registered view.

  • className - the className of the view you want to create
  • properties - the properties to assign to the created class

views.decorator(decorator)

Registers a view plugin. This is useful if you want to extend the functionality for each view. Super useful for interpolation between different libraries. Here's an example of paperclip using the handlebars template engine:

models

Property added by models extension when registering to the application.

models.register(classesOrClassName[, class])

Registers a globally accessible model class. Similar to how views.register(...) works.

  • classesOrClassName - classes, or class name
  • class - the class if className is provided

models.create(className, properties)

Creates a new registered model. Similar to how models.register(...) works.

models.decorate(decorator)

Registers a model extension. Works exactly like view extensions.

animate(animatable)

Added property by the animator. The animator plugin leverages the browsers native requestAnimationFrame function to update the DOM. It's used in views, and templates.

router

Added property from mojo-router. See HTTP Router docs for usage.

paperclip

Added property. See paperclip template extension for more details.


views.Base


Extends bindable.Object
Inherited By views.List, views.Stack
See also Application, Templates

Mojo views control exactly what the user sees & does. This is where all your view-specific logic should go.

View controllers are plugin-based - they don't come with any special features out of the box, such as a template engine. This allows you to fully customize exactly how view controllers behave. See the plugins section to understand how to extend view functionality.

Installation

npm install mojo-views --save-exact

Base(properties[, application])

The view constructor.

  • properties - values to set onto the view. This could be anything.
  • application - (optional) the application. Application.main will be set if this is omitted.

section

The virtual document fragment which contains all your elements. Note that this property is created after the view has been rendered.

Application application

The application. Views use the application to communicate with other parts of your program. The application also defines exactly how views behave through registered plugins.

Boolean visible

true if the view is visible. false if the view isn't.

DocumentFragment render()

Renders the view, and returns a document fragment

override didCreateSection()

Called when the section is created. This is called once during the lifetime of the view.

override willRender()

Called immediately before rendering the view

override didRender()

called immediately after rendering. At this point, all DOM elements should be created, and added to the view

remove()

Removes the view from the DOM

override willRemove()

called immediately before removing the view. Similar to willRender.

override didRemove()

called immediately after removing the view. Similar to didRemove.

Events

  • render - emitted when rendered
  • remove - emitted when removed
  • dispose - emitted when disposed

Property Scope

Views have the ability to inherit properties from their parent. Think of this a bit like variable scope. This mechanism is incredibly useful if you want to implicitly pass properties from one view to the other. For example:

Breaking Scope

In many cases, you might not want to inherit properties from the parent. To stop inheriting values, simply define whatever properties you want within each child view. This can be done either by setting properties in the prototype, or calling view.set(property, value). Here's an example:

The added benefit of breaking out of variable scope by defining them is that is also shows exactly what properties the view expects.

Extended API

Below are a list of optional extensions you can use for mojo views.

paper

Defined by the paperclip extension. The property expects either a compiled template (function), or string to compile. Here's an example:

bindings

Bindings allow you to compute properties on each view.

children

Children allow you to define child view controller which get added to the view controller. This allows a greater level of organization in your codebase. Here's an example of a basic view structure:


views.Stack


Extends views.Base
See Also http router

The stack view is a container with many children where only one is displayed at a time. Stack views are very useful when building Single Page Applications with navigation, and often times with something such as an HTTP router.

Installation

npm install mojo-views --save-exact

state

the current state of the stack view. This property is not inheritable.

states

Allows you to control the state of multiple nested stack. This property is inheritable, and usually set at the root view level.


views.List


Extends views.Base
See Also bindable.Collection, models.Collection

Creates a list of views which is represented by an array, or bindable.Collection.

Installation

npm install mojo-views --save-exact

source

The source of the list. This can be an array, or bindable.Collection (recommended). The list view creates, and appends a new instance of modelViewClass for each item in the list. Also note that the source can be a reference to a source, or a property which defines the source.

modelViewClass

The view class that's created for each model in source. Note that the property model is set to each listed view, as shown in the example above.

sort(modelA, modelB)

The sorting function for the list

filter(model)

Filters models from the list


templates


See Also bindable.Object, views.Base

Templates Provide the view in MVC - they're simply used to display information to the user, and relay user-interactions back to the view controller.

Paperclip takes on a mustache / handlebars approach with variables, blocks, and pollyfills. Paperclip also allows basic inline javascript, similar to angular.js.

Installation

npm install mojo-paperclip --save-exact

Template Syntax

{{ blocks }}

Variable blocks as placeholders for information that might change. For example:

You can also specify blocks within attributes.

Paperclip also supports inline javascript. For example:

Modifiers

Modifiers format data in a variable block. A good example of this might be presenting data to the user depending on their locale, or parsing data into markdown. Here are a few examples of how you can use modifiers:

Binding Operators

Paperclip comes with various binding operators that give you full control over how references are handled. You can easily specify whether to bind one way, two ways, or not at all. Here's the basic syntax:

Built-in components

{{ html: content }}

Similar to escaping content in mustache ({{{content}}}). Good for security.

{{ #if: condition }}

Conditional block helper

data-bind attributes

data-bind attributes are inspired by knockout.js. This is useful if you want to attach behavior to any DOM element.

{{ model: context }}

Input data-binding

Notice the <~> operator. This tells paperclip to bind both ways. See binding operators for more info.

{{ event: expression }}

Executed when an event is fired on the DOM element. Here are all the available events:

  • onChange - called when an element changes
  • onClick - called when an element is clicked
  • onLoad - called when an element loads - useful for <img />
  • onSubmit - called on submit - useful for <form />
  • onMouseDown - called on mouse down
  • onMouseUp - called on mouse up
  • onMouseOver - called on mouse over
  • onMouseOut - called on mouse out
  • onKeyDown - called on key down
  • onKeyUp - called on key up
  • onEnter - called on enter key up
  • onDelete - called on delete key up

{{ show: bool }}

Toggles the display mode of a given element. This is similar to the {{#if: expression }} conditional helper.

{{ css: styles }}

Sets the css of a given element. For example:

{{ style: styles }}

Sets the style of a given element.

{{ disable: bool }}

Toggles the enabled state of an element.

<button data-bind={{ disable: !formIsValid }}>Sign Up</button>

{{ focus: bool }}

Focuses cursor on an element.

<input data-bind={{ focus: true }}></input>

Basic API

paperclip([application])

initializes paperclip with the given application. Application.main will be used if this is omitted.

paperclip.modifier(modifierName, modifier)

registers a new paperclip modifier within the context of the application. See example above.

template paperclip.template(source)

Parses a template.

template.bind(context).render()

Binds a template, and returns a document fragment.

For core paperclip documentation, see Core API


models.Base


Extends bindable.Object
See Also models.Collection, Application

Models represent data, and implement properties, methods, and virtuals depending on how you need to interact with that data. Just like views, models are also extendable.

Installation

npm install mojo-models --save-exact

Base(properties[, application])

base model constructor

  • properties - values to set onto the view. This could be anything.
  • application - (optional) the application. Application.main will be set if this is omitted.

data

The raw data set on the model - this is usually transformed into something the model can use via deserialize.

deserialize(data)

deserialize takes the data property on the model, and transforms the returned values as additional properties on the model.

base.serialize()

serializes data. This is an alias to toJSON

Extended API

persist

Persistence layer for models / collections. Also adds the methods load, save, and remove.

model.load(onLoad)

Defined when persist is present, and calls persist.load.

  • onLoad - onLoad callback function. Expects an (err, data) response. data is set as the data property on the model, and gets deserialized.

Note that this method can be called only once during the lifetime of the model. If you want to reload the model, you'll need to call the reload method.

model.reload(onReload)

Reloads the model. This can be called many times.

model.save(onSave)

Similar to model.load. Calls the persist.save function, and sets result to data to be deserialized on the model.

model.remove(onRemove)

Removes the model. Note that if the model is part of a models.Collection, the model will automatically be removed from the collection.

Persist events

  • willSave - emitted when the model is about to be saved
  • didSave - emitted when the model has been saved
  • willRemove - emitted when the model is about to be removed
  • didRemove - emitted when the model has been removed

See above for example.

virtuals

Virtual properties allow you to load external resources on demand. This is especially useful when you're data-binding a model property to a view layer, and only what to load what the user currently needs.

Note that virtual properties are triggered when they are data-bound.

bindings

Bindings allow you to compute properties on models.


models.Collection


Extends bindable.Collection

Installation

npm install mojo-models --save-exact

Collection(properties[, application])

  • properties - properties to set on the collection

data

the raw source for the collection. Should be an array.

model createModel(options)

Creates a model. This method is usually defined when extending the base collection. It's also called when deserializing each item in data. See example above.

idProperty

The id property for each model. This id "_id" by default.

model create(properties)

creates a new model, and adds to the collection immediately. See example above.

deserialize(data)

Deserializes data, and sets the returned value as the source of the array.

serialize()

serializes collection into an array. alias to toJSON

Extended API

See extended api on models.Base


router


HTTP router which helps maintain application state.

Examples

Playground Example

Route Syntax

route.enter

route.name

Name of the route. It's recommended that you redirect with this incase the route ever changes.

route.states

The application state set by the route. This is used to change your UI state. See example above.

route parameters

Just like express.js, you have the ability to create parameter loaders.

nested routes

You can also nest routes.

API

router.redirect(pathnameOrRouteName[, options], complete)

  • pathnameOrRouteName - pathname or route name to redirect to
  • options - route name options
    • query - route query
    • params - route params
  • complete - called when redirected

router.add(routes)

adds new routes to the router

router.location

The current location of the router

router.bind("location", function () {
  // called whenever the location changes
});

location.query

query parameters on the location. Note that if the query changes, those changes will also be reflected in the HTTP url.

router.bind("location", function (err, location) {
  console.log(location.get("query.hello")); // blah
  location.set("query.hello", "world"); // gets reflected in the HTTP url
});

router.redirect("/home?hello=blah");

location.params

similar to location.query. location.params are taken from the route parameters.

location.url

pathname + query params.

router.bind("location", function (err, location) {
  console.log(location.get("url")); // /home?hello=blah
});

router.redirect("/home?hello=blah");

location.pathname

just the pathname of the location

location.redirect(pathname, options)

redirects the location


bindable.Object


Bindable Objects are the base class for most components including views, and models.

Two-way data binding means linking properties of two separate objects - when one changes, the other will automatically update with that change. It enables much easier interactions between data models and UIs, among other uses outside of MVC.

Installation

npm install bindable --save-exact

Object(properties)

creates a new bindable object

value get(property)

Returns a property on the bindable object

set(property, value)

Sets a value to the bindable object

setProperties(properties)

sets multiple properties on the bindable object

has(property)

Returns true if the bindable object has a given property

listener on(event, callback)

adds a new listener to the bindable object

emit(event[,args...])

emits a new event

once(event, callback)

listens to one event, then disposes the listener.

removeAllListeners([type])

returns all the listeners on the bindable object

binding bind(from, options)

options - the options for the binding

  • to - the property to bind to. Can be a string, array, or function
  • target - the target bindable object. Default is self
  • max - max number of times to run the data-binding
  • when - tests the data-bound value before setting
  • map - transforms the data-bound value
  • bothWays - makes the data-binding bi-directional.

binding.now()

Executes a binding now

binding.dispose()

Disposes a binding

Events

Bindable objects emit a few events:

  • change:* - emitted when a property changes on the bindable object. E.g: change:location.zip.
  • change - emitted when any property changes on the bindable object
  • watching - emitted when a property is being watched
  • dispose - emitted when dispose() is called on a bindable object


bindable.Collection


Extends bindable.Object

bindable.Collection operates like arrays, except they're watchable if anything changes.

Installation

npm install bindable --save-exact

Collection(source)

The constructor

source

The source of the collection. This is an array.

reset(source)

Resets the source of the collection. You can also do this by calling set('source', array)

indexOf(item)

returns the index of an item

value at(index)

returns an item at the given index

each(fn)

iterates through the collection. similar to array.forEach.

push(values...)

pushes items to the end of the collection.

unshift(values...)

unshifts items to the beginning of the collection.

splice(index, count[, newValues...])

removes items from the collection

value pop()

pops the last item off the collection

value shift()

removes the first item from the collection

Events

  • insert - emitted when items are inserted
  • update - emitted when the collection is updated
  • reset - emitted when the source has been reset
  • remove - emitted when items have been removed


mojo-cli


Utility for compiling your mojo application into a single page application. This utility assumes that your application is written using CommonJS.

Installation

In your application directory, run this command:

npm install mojo-cli --save

Make sure your package.json looks something like this:

{

  // script for bundling the application into one file
  "scripts": {
    "build": "./node_modules/.bin/mojo . -m --output=./build/app.bundle.js"
  },

  // additional browser files that get compiled using browserify
  "browser": {
    "jquery": "./vendor/path/to/jquery.js"
  },
  "main": "./lib/index.js"
}

then run

npm run build

Examples

Usage

Usage: mojo [options] [command]

Commands:

  build [path]           builds a project

Options:

  -h, --help    output usage information
  -m, --minify  minify output
  -p, --port    http port
  -o, --output  output file
  -s, --serve   directory to server

Examples

building a project:

mojo build ./path/to/project.js --output=./build/app.js

minify a project:

mojo build ./path/to/project.js --minify --output=./build/app.js

build a project, and serve it:

mojo build ./path/to/project.js --minify --output=./build/app.js --server=./build --port=8085