javascriptmvc-doc

来源:互联网 发布:公安现场绘图软件 编辑:程序博客网 时间:2024/04/27 20:45

JavaScriptMVC Documentation

JavaScriptMVC (JMVC) is a MIT licensed,client-side, JavaScript framework that builds maintainable, error-free,lightweight applications as quick as possible. It packs best-of-breed librariesand tools that are guaranteed to work together. It supports every browser thatjQuery supports.

If you are new to the framework, thispage followed by thetutorials is the best place to start.

JMVC's goodies are broken down into foursub-projects:

·        jQueryMX - jQuery MVC and DOM extensions

·        StealJS - JavaScript and CSS dependencymanagement and build tools

·        FuncUnit - Functional and unit testing framework

·        DocumentJS - Documentation engine

JavaScriptMVC is extremely modular. Useeach sub-project together or separately (via thedownload builder). Start small, using only$.Controller and add in parts of the framework asnecessary.

The remainder of this page highlightseach sub-project. Click the the project links on the left for a more in-depthoverview of the sub-project.

jQueryMX

jQueryMX is a collection of useful jQuerylibraries that provide the missing functionality necessary to implement andorganize large-scale jQuery applications. For example, it includes things like:

·        Special events likedrag-drop and resize

·        Language helpers liketoJSON and anobservable system

·        DOM extensions for things liketext ranges andcookies

·        Browser historyrouting.

·        Aclass-like system

jQueryMX also puts the MVC in JavaScriptwith $.Model, $.View, and $.Controller.Models connect to your server over a RESTfulJSON interface.Views are super-charged client sidetemplates.Controllers prevent memory leaks with declarativeevent handling.

jQueryMX is very lightweight. It's MVClibraries combined (including their $.Class dependency) are 7kb minified andgzipped. Furthermore, you can use every part of jQueryMX independently ofJavaScriptMVC and even independently of other parts of jQueryMX. For example,you can use $.Controller without $.Model.

StealJS

StealJS is a "code manager" thatkeeps code beautiful and organized while developing and FAST for users inproduction. It's a collection of command-line and browser-based utilitiesenabling you to:

·        load JS, CSS, LESS, and CoffeeScript filesand build them into a single production file.

·        generate an application file/folder structure,complete with test, build and documentation scripts.

·        install 3rd party dependencies.

·        clean and JSLint your code.

·        make your Ajax appcrawlable.

·        logmessages in development that get removed inproduction builds.

StealJS is a stand-alone tool that can be usedwithout the rest of JavaScriptMVC.

FuncUnit

FuncUnit is a web application testing frameworkthat provides automated unit and functional testing. Tests are written anddebugged in the browser with FuncUnit's short, terse, jQuery-like API. The sametests can be instantly automated, run by Envjs or Selenium.

FuncUnit also supports extremelyaccurateevent simulation on practically every browser andsystem.

DocumentJS

DocumentJS provides powerful JavaScriptdocumenting capabilities. This whole website is built with it! DocumentJS candocument practically anything. It's extensible. And with Markdown support, it'seasy to document your code.

 

 

 

 

jQueryMXpage

jQueryMX is a collection of usefuljQuery libraries that provide the missing functionality necessary to implementand organize large-scale jQuery applications.

Every part of jQueryMX can be usedstand-alone which keeps your app super light. $.Model, $.View, and $.Controllerare only 7kb minified and gzipped. This includs their $.String, $.Class, anddestroyed-event dependencies.

If you are using steal, simply steal the plugin you need like:

steal('jquery/controller',function(){

  $.Controller('Tabs');

})

Or, use the download builder to select the files you need.

jQueryMX is divided into four coreareas:

·        DOM Helpers

·        Language Helpers

·        Special events

·        Model, View, Controller and Class ( Readthe walkthrough )

The following highlights jQueryMX'sfunctionality.

DOMHelpers

DOM helpers extend jQuery with extra functionalityfor manipulating the DOM. For example,dimensions lets you set the outer width and heightof elements like:

$('#foo').outerWidth(500);

THe following are the other dom plugins:

·        Cookie - Set and get cookie values.

·        Fixture - Simulate Ajax responses.

·        Closest - Use the open child selector in eventdelegation.

·        Compare - Compare the location of two elementsrapidly.

·        CurStyles - Get multiple css properties quickly.

·        FormParams - Serializes a form into a JSON-likeobject.

·        Selection - Gets or sets the current textselection.

·        Within - Returns elements that have a pointwithin their boundaries.

·        Range - Text range utilities.

·        jQuery.route - Routes for history-enabled ajax apps.

SpecialEvents

jQueryMX comes packed with jQuery special events and event helpers.

·        Drag - Delegatable drag events.

·        Drop - Delegatable drop events.

·        Hover - Delegatable hover events.

·        Destroyed - Know when an element is removed fromthe page.

·        Resize - Listen to resize events on anyelement.

·        Swipe - Delegatable swipe events.

·        Key - Get the character from a key event.

·        Default - Provide default behaviors for events.

·        Pause-Resume - Pause and resume event propagation.

LanguageHelpers

Language helpers make it easy to performvarious functions on JavaScript data.

·        Object - compare objects and sets

·        Observe - Listen to changes in JS Objects andArrays

·        String - String helpers

·        toJSON - create and convert JSON strings

·        Vector - vector math

$.Class

$.Class provides simple prototypal inheritance.It's used by$.Controller and$.Model.

// create a Monster Class

$.Class("Monster",

// static methods

{

 

  // a list of all monsters

  monsters : []

},

// prototype methods

{

 

  // called when a new monster is created

  init : function(name){

 

    // stores a reference to the name

    this.name = name;

 

    // adds this monster to the collection ofmonsters

    this.Class.monsters.push(this);

  },

 

  // a method on monsters

  speak : function(){

    alert(this.name +"says hello.");

  }

});

 

// create a monster

var hydra =new Monster("hydra");   

 

// call a method on a monster

hydra.speak();

$.Model

$.Model encapsulates the service and datalayer. The following connects to a JSON REST service and adds a helper to letus know if we can destroy a task:

$.Model("Task",{

  findAll : "GET /tasks.json",

  findOne : "GET /tasks/{id}.json",

  create  : "POST/tasks.json",

  update  : "PUT/tasks/{id}.json",

  destroy : "DELETE /tasks/{id}.json"

},{

  canDestroy : function(){

    returnthis.acl.indexOf('w') > -1

  }

});

Assuming '/tasks.json' returns a JSONarray like ...

[{

  "id"       : 1,

  "name"     :"take out trash",

  "acl"      :"rw",

  "createdAt": 1303000731164// April 16 2011

},

{

  "id"       : 2,

  "name"     :"do the dishes",

  "acl"      :"r" ,

  "createdAt": 1303087131164// April 17 2011

}]

... the following will retrieve alltasks from the server and then destroy tasks that the user is able to destroy:

Task.findAll({}, function(tasks){

  for(var i =0; i <tasks.length; i++){

 

    var task = tasks[i];

 

    if( task.canDestroy() ){

     task.destroy();

    }

  }

});

Model has a number of other usefulfeatures such as:

·        Listening to [jquery.model.events events].

·        //listen to name changes on a task

·        task.bind("name",function(ev, newName){

·           alert('task name = '+newName);

·        });

·         

·        //changethe task's name

·        task.attr('name',"laundry");

·         

·        //listenfor Tasks being created:

·        Task.bind("created",function(ev, newTask){

·           // create newTask's html and add it to thepage

});

·        Converting raw data into more useful objects.

·        $.Model('Task', {

·          convert  : {

·            'date' :function(raw){

·              returnnew Date(raw)

·            }

·          },

·          attributes : {

·            'createdAt' :'date'

·          }

·        },{});

·         

·        var task =new Task({ createdAt :1303087131164});

·         

·        //createdAt is now a date.

task.createdAt.getFullYear()// -> 2011

·        Methods and utilities onlists of instances.

·        //define a task list

·        $.Model.List('Task.List',{

·         

·          // add a helper method to a collection oftasks

·          canDestroyAll :function(){

·         

·            returnthis.grep(function(task){

·              return task.canDestroy();

·            }).length ===this.length

·          }

·        });

·         

·        Task.findAll({},function(tasks){

·         

·          //tasks is a Task.List

·          tasks.canDestroyAll()//-> boolean

})

·        Deferreds

·        //make 2 requests, and do something when they are

·        //both complete

·         

·        $.when( Task.findAll(), People.findAll() )

·          .done(function(tasks, people){

·         

·          // do something cool!

})

$.View

$.View is a template framework. It allows youto use different template engines in the same way.

The following requests tasks from themodel, then loads a template at"task/views/tasks.ejs", renders it with tasks, and inserts the result in the#tasks element.

Task.findAll( {}, function(tasks){

 

  $('#tasks').html('task/views/tasks.ejs', tasks );

});

tasks.ejs might look like:

<% $.each(this,function(task){ %>

  <li><%=task.name %></li>

<% }) %>

$.View understands deferreds so the following does the exact samething!

 $('#tasks').html('task/views/tasks.ejs', Task.findAll() );

Any template engine can be used with$.View. JavaScriptMVC comes with:

·        jQuery.EJS

·        Jaml

·        Micro

·        jQuery.tmpl

$.Controller

$.Controller is a jQuery widget factory. The followingcreates a$.fn.listplugin that writes a message into an element:

$.Controller( "List", {

  init: function( ) {

    this.element.text(this.options.message );

  }

});

 

// create the list

$('#list').list({message:"Hello World"});

$.Controller lets you define default options:

$.Controller( "List", {

  defaults: {

    message : "I am list"

  }

},{

  init: function( ) {

    this.element.text(this.options.message );

  }

});

 

// create's a list that writes "I am list"

$('#list').list();

Controller's best feature is that itorganizes your event handlers, and makesbinding and unbinding event handlers extremely easy. Thefollowing listens for clicks on anLI elements andalerts the element's text:

$.Controller( "TaskList", {

  init: function(){

    // uses a view to render tasks

    this.element.html("tasks.ejs", Task.findAll() );

  },

  "li click":function(el){

    alert(el.text() );

  }

});

Controller makes it easy to parameterizeevent binding. The following listens for tasks being created and inserts theminto the list:

$.Controller( "TaskList", {

  init: function( ) {

    // uses a view to render tasks

    this.element.html("tasks.ejs", Task.findAll());

  },

  "{Task} created":function( Task,ev, newTask ) {

    this.element.append("tasks.ejs", [newTask] );

  }

});

Finally, this makes it very easy tocreate widgets that work with any model:

$.Controller( "List", {

  init: function(){

    // uses a view to render tasks

    this.element.html(this.options.view,

                      this.options.model.findAll( ));

  },

  "{model} created":function(Model, ev, instance ){

    this.element.append(this.options.view, [instance] );

  }

});

 

$("#tasks").list({ model: Task, view:'tasks.ejs' });

$("#people").list({model: Person, view:'people.ejs' });

 

 

 

 

 

DOM Helperspage

Source

JavaScriptMVC adds a bunch of usefuljQuery extensions for the dom. Check them out on the left.

Dimensions

Set and animate the inner and outerheight and width of elements.

$('#foo').outerWidth(100);

$('#bar').animate({innerWidth: 500});

This is great when you want to include paddingand margin in setting the dimensions of elements.

Cookie

Set and get cookie values:

$.cookie('cookie','value');

Fixture

Simulate Ajax responses.

$.fixture("/services/tasks.php','fixtures/tasks.json');

Works with jQuery's Ajax converters!

Compare

Compare the location of two elementsrapidly.

$('#foo').compare($('#bar')) & 2// true if #bar is before #foo

CurStyles

Get multiple css properties quickly.

$('#foo').curStyles('left','top')//-> {left:'20px',top:'10px'}

FormParams

Serializes a form into a JSON-likeobject:

$('form').formParams()//-> {name: 'Justin', favs:['JS','Ruby']}

Selection

Gets or sets the current text selection.

// gets selection info

$('pre').selection()//-> {start: 22, end: 57, range: range}

 

// sets the selection

$('div').selection(20,22)

Within

Returns elements that have a pointwithin their boundaries.

$('.drop').within(200,200)//-> drops thattouch 200,200

Range

Text range utilities.

$('#copy').range()//-> text range that has copy selected

jQuery.route

Hash routes mapped to an $.Observe.

$.route(':type',{type:'videos'})

$.route.delegate('type','set',function(){ ... })

$.route.attr('type','images');

 

 

 

 

jQuery.Class class

plugin:jquery/class

download:jQuery.Class

test:qunit.html

Source

Class provides simulated inheritance in JavaScript. Use Class tobridge the gap between jQuery's functional programming style and ObjectOriented Programming. It is based off John Resig'sSimpleClass Inheritance library. Besides prototypalinheritance, it includes a few important features:

  • Static inheritance
  • Introspection
  • Namespaces
  • Setup and initialization methods
  • Easy callback function creation

The GetStarted with jQueryMX has a good walkthrough of$.Class.

Static v.Prototype

Before learning about Class, it's important to understand thedifference between a class'sstaticand prototypeproperties.

//STATIC
MyClass.staticProperty  //shared property
 
//PROTOTYPE
myclass = new MyClass()
myclass.prototypeMethod() //instance method

A static (or class) property is on the Class constructorfunction itself and can be thought of being shared by all instances of theClass. Prototype propertes are available only on instances of the Class.

A Basic Class

The following creates a Monster class with a name (forintrospection), static, and prototype members. Every time a monster instance iscreated, the static count is incremented.

$.Class('Monster',
/* @static */
{
  count: 0
},
/* @prototype */
{
  init: function( name ) {
 
    // saves name on the monster instance
    this.name = name;
 
    // sets the health
    this.health = 10;
 
    // increments count
    this.constructor.count++;
  },
  eat: function( smallChildren ){
    this.health += smallChildren;
  },
  fight: function() {
    this.health -= 2;
  }
});
 
hydra = new Monster('hydra');
 
dragon = new Monster('dragon');
 
hydra.name        // -> hydra
Monster.count     // -> 2
Monster.shortName // -> 'Monster'
 
hydra.eat(2);     // health = 12
 
dragon.fight();   // health = 8

Notice that the prototype init function is called when anew instance of Monster is created.

Inheritance

When a class is extended, all static and prototype propertiesare available on the new class. If you overwrite a function, you can call thebase class's function by callingthis._super. Lets create a SeaMonsterclass. SeaMonsters are less efficient at eating small children, but morepowerful fighters.

Monster("SeaMonster",{
  eat: function( smallChildren ) {
    this._super(smallChildren / 2);
  },
  fight: function() {
    this.health -= 1;
  }
});
 
lockNess = new SeaMonster('Lock Ness');
lockNess.eat(4);   //health = 12
lockNess.fight();  //health = 11

Staticproperty inheritance

You can also inherit static properties in the same way:

$.Class("First",
{
    staticMethod: function() { return 1;}
},{})
 
First("Second",{
    staticMethod: function() { return this._super()+1;}
},{})
 
Second.staticMethod() // -> 2

Namespaces

Namespaces are a good idea! We encourage you to namespace all ofyour code. It makes it possible to drop your code into another app withoutproblems. Making a namespaced class is easy:

$.Class("MyNamespace.MyClass",{},{});
 
new MyNamespace.MyClass()

Introspection

Often, it's nice to create classes whose name helps determinefunctionality. Ruby on Rails'sActiveRecordORM class is a great example of this. Unfortunately, JavaScript doesn't have away of determining an object's name, so the developer must provide a name.Class fixes this by taking a String name for the class.

$.Class("MyOrg.MyClass",{},{})
MyOrg.MyClass.shortName //-> 'MyClass'
MyOrg.MyClass.fullName //->  'MyOrg.MyClass'

The fullName (with namespaces) and the shortName (withoutnamespaces) are added to the Class's static properties.

Setup andinitialization methods

Class provides static and prototype initialization functions.These come in two flavors - setup and init. Setup is called before init and canbe used to 'normalize' init's arguments.

PRO TIP: Typically, you don't need setup methods in yourclasses. Use Init instead. Reserve setup methods for when you need to docomplex pre-processing of your class before init is called.

$.Class("MyClass",
{
  setup: function() {} //static setup
  init: function() {} //static constructor
},
{
  setup: function() {} //prototype setup
  init: function() {} //prototype constructor
})

Setup

Setup functions are called before init functions. Static setupfunctions are passed the base class followed by arguments passed to the extendfunction. Prototype static functions are passed the Class constructor functionarguments.

If a setup function returns an array, that array will be used asthe arguments for the following init method. This provides setup functions theability to normalize arguments passed to the init constructors. They are alsoexcellent places to put setup code you want to almost always run.

The following is similar to how jQuery.Controller.prototype.setupmakes sure init is always called with a jQuery element and merged options evenif it is passed a raw HTMLElement and no second parameter.

$.Class("jQuery.Controller",{
  ...
},{
  setup: function( el, options ) {
    ...
    return [$(el),
            $.extend(true,
               this.Class.defaults,
               options || {} ) ]
  }
})

Typically, you won't need to make or overwrite setup functions.

Init

Init functions are called after setup functions. Typically, theyreceive the same arguments as their preceding setup function. The Foo class'sinit method gets called inthe following example:

$.Class("Foo", {
  init: function( arg1, arg2, arg3 ) {
    this.sum = arg1+arg2+arg3;
  }
})
var foo = new Foo(1,2,3);
foo.sum //-> 6

Proxies

Similar to jQuery's proxy method, Class provides aproxyfunction that returns a callback to a method that will always havethis set to the class orinstance of the class.

The following example uses this.proxy to make surethis.name isavailable inshow.

$.Class("Todo",{
  init: function( name ) { 
      this.name = name 
  },
  get: function() {
    $.get("/stuff",this.proxy('show'))
  },
  show: function( txt ) {
    alert(this.name+txt)
  }
})
new Todo("Trash").get()

Callback is available as a static and prototype method.

Demo

Demo

HTML

<H2>BasicTabs</H2>

<UL id=tabs1 class=ui-helper-clearfix ?>

<LI><A href="#tab1">Tab1</A></LI>

<LI><A href="#tab2">Tab2</A></LI>

<LI><A href="#tab3">Tab3</A></LI></UL>

<DIV id=tab1 class=tab>Tab1 Content</DIV>

<DIV id=tab2 class=tab>Tab2 Content</DIV>

<DIV id=tab3 class=tab>Tab3 Content</DIV>

<H2>HistoryTabs</H2>

<UL id=tabs2 class=ui-helper-clearfix ?>

<LI><A href="#tab4">Tab4</A></LI>

<LI><A href="#tab5">Tab5</A></LI>

<LI><A href="#tab6">Tab6</A></LI></UL>

<DIV id=tab4 class=tab>Tab4 Content</DIV>

<DIV id=tab5 class=tab>Tab5 Content</DIV>

<DIV id=tab6 class=tab>Tab6 Content</DIV>

Source

steal('jquery/controller').then(function(){

$.Controller("Tabs",{

  init : function(){

    this.element.children("li:first").addClass('active')

    var tab = this.tab;

    this.element.children("li:gt(0)").each(function(){

      tab($(this)).hide()

    })

  },

  tab : function(li){

    return$(li.find("a").attr("href"))

  },

  "li click": function(el, ev){

    ev.preventDefault();

    this.activate(el)

  },

  activate : function(el){

    this.tab(this.find('.active').removeClass('active')).hide()

    this.tab(el.addClass('active')).show();

  }

})

 

//inherit from tabs

Tabs("HistoryTabs",{

 

  // ignore clicks

  "li click": function(){},

 

  // listen forhistory changes

  "{window}hashchange" : function(ev){

    var hash =window.location.hash;

    this.activate(hash=== '' || hash === '#' ?

        this.element.find("li:first") :

        this.element.find("a[href="+hash+"]").parent()

      )

  }

})

 

//adds the controller to theelement

$("#tabs1").tabs();

$("#tabs2").history_tabs();

})

Constructor

To create a Class call:

$.Class( [NAME , STATIC,] PROTOTYPE ) -> Class

NAME{optional:String}

If provided, this sets theshortName and fullName of the class and adds it and any necessary namespaces tothe window object.

STATIC{optional:Object}

If provided, this createsstatic properties and methods on the class.

PROTOTYPE{Object}

Creates prototype methods onthe class.

When a Class is created, the static setupand [jQuery.Class.static.init init] methods are called.

To create an instance of a Class, call:

new Class([args ... ]) -> instance

The created instance will have all the prototype properties andmethods defined by the PROTOTYPE object.

When an instance is created, the prototype setupandinitmethods are called.

new $.Class() -> jquery.class

returns {jquery.class}

 

 

 

jQuery.Controller class

inherits:jQuery.Class

plugin:jquery/controller

download:jQuery.Controller

test:qunit.html

Source

jQuery.Controller helps create organized, memory-leak free,rapidly performing jQuery widgets. Its extreme flexibility allows it to serveas both a traditional View and a traditional Controller.

This means it is used to create things like tabs, grids, andcontextmenus as well as organizing them into higher-order business rules.

Controllers make your code deterministic, reusable, organizedand can tear themselves down auto-magically. Read aboutthetheory behind controller and awalkthroughof its features on Jupiter's blog.GetStarted with jQueryMX also has a great walkthrough.

Controller inherits from $.Classand makes heavy use ofevent delegation.Make sure you understand these concepts before using it.

Basic Example

Instead of

$(function(){
  $('#tabs').click(someCallbackFunction1)
  $('#tabs .tab').click(someCallbackFunction2)
  $('#tabs .delete click').click(someCallbackFunction3)
});

do this

$.Controller('Tabs',{
  click: function() {...},
  '.tab click' : function() {...},
  '.delete click' : function() {...}
})
$('#tabs').tabs();

Tabs Example

Demo

HTML

<UL id=tabs class=ui-helper-clearfix ?>

<LI><A href="#tab1">Tab1</A>

<LI><A href="#tab2">Tab2</A>

<LI><A href="#tab3">Tab3</A></LI></UL>

<DIV id=tab1 class=tab>Tab1 Content</DIV>

<DIV id=tab2 class=tab>Tab2 Content</DIV>

<DIV id=tab3 class=tab>Tab3 Content</DIV>

Source

steal("jquery/controller",function(){

// create a new Tabs class

$.Controller("Tabs",{

 

  // initializewidget

  init : function(el){

   

    // activate thefirst tab

    $(el).children("li:first").addClass('active')

   

    // hide theother tabs

    var tab = this.tab;

    this.element.children("li:gt(0)").each(function(){

      tab($(this)).hide()

    })

  },

 

  // helper functionfinds the tab for a given li

  tab : function(li){

    return$(li.find("a").attr("href"))

  },

 

  // hides oldactive tab, shows new one

  "li click": function(el, ev){

    ev.preventDefault();

    this.tab(this.find('.active').removeClass('active')).hide()

    this.tab(el.addClass('active')).show();

  }

})

 

// adds the controller to theelement

$("#tabs").tabs();

})

Using Controller

Controller helps you build and organize jQuery plugins. It canbe used to build simple widgets, like a slider, or organize multiple widgetsinto something greater.

To understand how to use Controller, you need to understand thetypical lifecycle of a jQuery widget and how that maps to controller'sfunctionality:

Acontroller class is created.

$.Controller("MyWidget",
{
  defaults :  {
    message : "Remove Me"
  }
},
{
  init : function(rawEl, rawOptions){ 
    this.element.append(
       "<div>"+this.options.message+"</div>"
      );
  },
  "div click" : function(div, ev){ 
    div.remove();
  }  
}) 

This creates a $.fn.my_widget jQuery helper functionthat can be used to create a new controller instance on an element. Find moreinformationhereabout the plugin gets created and the rules around its name.

Aninstance of controller is created on an element

$('.thing').my_widget(options) // calls new MyWidget(el, options)

This calls new MyWidget(el, options) oneach'.thing'element.

When a new Classinstance is created, it calls the class's prototype setup and init methods.Controller'ssetupmethod:

  • Sets this.element and adds the controller's name to element's className.
  • Merges passed in options with defaults object and sets it asthis.options
  • Saves a reference to the controller in $.data.
  • Binds all event handler methods.

Thecontroller responds to events

Typically, Controller event handlers are automatically bound.However, there are multiple ways tolistento events with a controller.

Once an event does happen, the callback function is alwayscalled with 'this' referencing the controller instance. This makes it easy touse helper functions and save state on the controller.

Thewidget is destroyed

If the element is removed from the page, the controller'sjQuery.Controller.prototype.destroymethod is called. This is a great place to put any additional teardownfunctionality.

You can also teardown a controller programatically like:

$('.thing').my_widget('destroy');

Todos Example

Lets look at a very basic example - a list of todos and a buttonyou want to click to create a new todo. Your HTML might look like:

<div id='todos'>
 <ol>
   <li class="todo">Laundry</li>
   <li class="todo">Dishes</li>
   <li class="todo">Walk Dog</li>
 </ol>
 <a class="create">Create</a>
</div>

To add a mousover effect and create todos, your controller mightlook like:

$.Controller('Todos',{
  ".todo mouseover" : function( el, ev ) {
    el.css("backgroundColor","red")
  },
  ".todo mouseout" : function( el, ev ) {
    el.css("backgroundColor","")
  },
  ".create click" : function() {
    this.find("ol").append("<li class='todo'>New Todo</li>"); 
  }
})

Now that you've created the controller class, you've must attachthe event handlers on the '#todos' div by creatinga newcontroller instance. There are 2 ways of doingthis.

//1. Create a new controller directly:
new Todos($('#todos'));
//2. Use jQuery function
$('#todos').todos();

ControllerInitialization

It can be extremely useful to add an init method with setupfunctionality for your widget.

In the following example, I create a controller that whencreated, will put a message as the content of the element:

$.Controller("SpecialController",
{
  init: function( el, message ) {
    this.element.html(message)
  }
})
$(".special").special("Hello World")

RemovingControllers

Controller removal is built into jQuery. So to remove acontroller, you just have to remove its element:

$(".special_controller").remove()
$("#containsControllers").html("")

It's important to note that if you use raw DOM methods (innerHTML, removeChild), thecontrollers won't be destroyed.

If you just want to remove controller functionality, calldestroy on the controller instance:

$(".special_controller").controller().destroy()

AccessingControllers

Often you need to get a reference to a controller, there are afew ways of doing that. For the following example, we assume there are 2elements withclassName="special".

//creates 2 foo controllers
$(".special").foo()
 
//creates 2 bar controllers
$(".special").bar()
 
//gets all controllers on all elements:
$(".special").controllers() //-> [foo, bar, foo, bar]
 
//gets only foo controllers
$(".special").controllers(FooController) //-> [foo, foo]
 
//gets all bar controllers
$(".special").controllers(BarController) //-> [bar, bar]
 
//gets first controller
$(".special").controller() //-> foo
 
//gets foo controller via data
$(".special").data("controllers")["FooController"] //-> foo

Calling methodson Controllers

Once you have a reference to an element, you can call methods onit. However, Controller has a few shortcuts:

//creates foo controller
$(".special").foo({name: "value"})
 
//calls FooController.prototype.update
$(".special").foo({name: "value2"})
 
//calls FooController.prototype.bar
$(".special").foo("bar","something I want to pass")

These methods let you call one controller from anothercontroller.

 

 

 

jQuery.Model class

plugin:jquery/model

download:jQuery.Model

test:qunit.html

Source

Models super-charge an application's data layer, making it easyto:

  • Get and modify data from the server
  • Listen to changes in data
  • Setting and retrieving models on elements
  • Deal with lists of data
  • Do other good stuff

Model inherits from $.Classand make use of REST services anddeferredsso these concepts are worth exploring. Also, theGetStarted with jQueryMX has a good walkthrough of$.Model.

Get and modifydata from the server

$.Model makes connecting to a JSON REST service really easy. Thefollowing modelstodosby describing the services that can create, retrieve, update, and delete todos.

$.Model('Todo',{
  findAll: 'GET /todos.json',
  findOne: 'GET /todos/{id}.json',
  create:  'POST /todos.json',
  update:  'PUT /todos/{id}.json',
  destroy: 'DELETE /todos/{id}.json' 
},{});

This lets you create, retrieve, update, and delete todosprogramatically:

Create

Create a todo instance and call save(success, error) tocreate the todo on the server.

// create a todo instance
var todo = new Todo({name: "do the dishes"})
 
// save it on the server
todo.save();

Retrieve

Retrieve a list of todos from the server with findAll(params, callback(items)):

Todo.findAll({}, function( todos ){
 
  // print out the todo names
  $.each(todos, function(i, todo){
    console.log( todo.name );
  });
});

Retrieve a single todo from the server with findOne(params, callback(item)):

Todo.findOne({id: 5}, function( todo ){
 
  // print out the todo name
  console.log( todo.name );
});

Update

Once an item has been created on the server, you can change itsproperties and callsaveto update it on the server.

// update the todos' name
todo.attr('name','Take out the trash')
 
// update it on the server
todo.save()

Destroy

Call destroy(success, error) todelete an item on the server.

todo.destroy()

Listen to changesin data

Listening to changes in data is a critical part of theModel-View-Controllerarchitecture. $.Model lets you listen to when an item is created, updated,destroyed or its properties are changed. Use Model.bind(eventType, handler(event, model))to listen to all events of type on a model andmodel.bind(eventType, handler(event)) tolisten to events on a specific instance.

Create

// listen for when any todo is created
Todo.bind('created', function( ev, todo ) {...})
 
// listen for when a specific todo is created
var todo = new Todo({name: 'do dishes'})
todo.bind('created', function( ev ) {...})

Update

// listen for when any todo is updated
Todo.bind('updated', function( ev, todo ) {...})
 
// listen for when a specific todo is created
Todo.findOne({id: 6}, function( todo ) {
  todo.bind('updated', function( ev ) {...})
})

Destroy

// listen for when any todo is destroyed
Todo.bind('destroyed', function( ev, todo ) {...})
 
// listen for when a specific todo is destroyed
todo.bind('destroyed', function( ev ) {...})

Property Changes

// listen for when the name property changes
todo.bind('name', function(ev){  })

Listening with Controller

You should be using controller to listen to model changes like:

$.Controller('Todos',{
  "{Todo} updated" : function(Todo, ev, todo) {...}
})

Setting andretrieving data on elements

Almost always, we use HTMLElements to represent data to theuser. When that data changes, we update those elements to reflect the new data.

$.Model has helper methods that make this easy. They let you"add" a model to an element and also find all elements that have hada model "added" to them.

Consider a todo list widget that lists each todo in the page andwhen a todo is deleted, removes it.

$.fn.model(item) lets you set or read a modelinstance from an element:

Todo.findAll({}, function( todos ) {
 
  $.each(todos, function(todo) {
    $('<li>').model(todo)
             .text(todo.name)
             .appendTo('#todos')
  });
});

When a todo is deleted, get its element with item.elements(context) and remove it from thepage.

Todo.bind('destroyed', function( ev, todo ) { 
  todo.elements( $('#todos') ).remove()
})

Using EJS and $.Controller

$.ViewandEJSmakes adding model data to elements easy. We can implement the todos widgetlike the following:

$.Controller('Todos',{
  init: function(){
    this.element.html('//todos/views/todos.ejs', Todo.findAll({}) ); 
  },
  "{Todo} destroyed": function(Todo, ev, todo) {
    todo.elements( this.element ).remove()
  }
})

In todos.ejs

<% for(var i =0; i < todos.length; i++){ %>
  <li <%= todos[i] %>><%= todos[i].name %></li>
<% } %>

Notice how you can add a model to an element with <%= model %>

Lists

$.Model.Listlets you handle multiple model instances with ease. A List acts just like anArray, but you can addspecial properties to it and listen to events on it.

$.Model.Listhas become its own plugin, read about ithere.

Other Good Stuff

Model can make a lot of other common tasks much easier.

TypeConversion

Data from the server often needs massaging to make it moreuseful for JavaScript. A typical example is date data which is commonly passedas a number representing the Julian date like:

{ name: 'take out trash', 
  id: 1,
  dueDate: 1303173531164 }

But instead, you want a JavaScript date object:

date.attr('dueDate') //-> new Date(1303173531164)

By defining property-type pairs in attributes,you can have model auto-convert values from the server into more useful types:

$.Model('Todo',{
  attributes : {
    dueDate: 'date'
  }
},{})

Associations

The attributesproperty also supports associations. For example, todo data might come backwith User data as an owner property like:

{ name: 'take out trash', 
  id: 1, 
  owner: { name: 'Justin', id: 3} }

To convert owner into a User model, set the owner type as theUser'smodel( data )method:

$.Model('Todo',{
  attributes : {
    owner: 'User.model'
  }
},{})

HelperFunctions

Often, you need to perform repeated calculations with a model'sdata. You can create methods in the model's prototype and they will beavailable on all model instances.

The following creates a timeRemaining methodthat returns the number of seconds left to complete the todo:

$.Model('Todo',{
},{
   timeRemaining : function(){
     return new Date() - new Date(this.dueDate)
   }
})
 
// create a todo
var todo = new Todo({dueDate: new Date()});
 
// show off timeRemaining
todo.timeRemaining() //-> Number

Deferreds

Model methods that make requests to the server such as:findAll,findOne,save,anddestroyreturn adeferredthat resolves to the item(s) being retrieved or modified.

Deferreds can make a lot of asynchronous code much easier. Forexample, the following waits for all users and tasks before continuing :

$.when(Task.findAll(), User.findAll())
  .then(function( tasksRes, usersRes ){ ... })

Validations

Validateyour model's attributes.

$.Model("Contact",{
init : function(){
    this.validate("birthday",function(){
        if(this.birthday > new Date){
            return "your birthday needs to be in the past"
        }
    })
}
,{});

 

 

 

jQuery.Viewclass

plugin: jquery/view

download: jQuery.View

test: qunit.html

Source

View provides a uniform interface forusing templates with jQuery. When template enginesregister themselves, you are able to:

·        Use views with jQuery extensionsafter,append,before,html,prepend,replaceWith,text.

·        Template loading from html elements and external files.

·        Synchronous and asynchronous template loading.

·        Deferred Rendering.

·        Template caching.

·        Bundling of processed templates in production builds.

·        Hookup jquery plugins directly in the template.

The Get Started with jQueryMX has a good walkthrough of $.View.

Use

When using views, you're almost alwayswanting to insert the results of a rendered template into the page. jQuery.Viewoverwrites the jQuery modifiers so using a view is as easy as:

$("#foo").html('mytemplate.ejs',{message:'helloworld'})

This code:

·        Loads the template a 'mytemplate.ejs'. It might looklike:

<h2><%= message %></h2>

·        Renders it with {message: 'hello world'}, resulting in:

<div id='foo'>"<h2>helloworld</h2></div>

·        Inserts the result into the foo element. Foo might looklike:

<div id='foo'><h2>hello world</h2></div>

jQueryModifiers

You can use a template with thefollowing jQuery modifiers:

after

$('#bar').after('temp.jaml',{});

append

$('#bar').append('temp.jaml',{});

before

$('#bar').before('temp.jaml',{});

html

$('#bar').html('temp.jaml',{});

prepend

$('#bar').prepend('temp.jaml',{});

replaceWith

$('#bar').replaceWith('temp.jaml',{});

text

$('#bar').text('temp.jaml',{});

You always have to pass a string and anobject (or function) for the jQuery modifier to user a template.

TemplateLocations

View can load from script tags or fromfiles.

FromScript Tags

To load from a script tag, create ascript tag with your template and an id like:

<script type='text/ejs' id='recipes'>

<% for(var i=0; i < recipes.length; i++){ %>

 <li><%=recipes[i].name %></li>

<%}%>

</script>

Render with this template like:

$("#foo").html('recipes',recipeData)

Notice we passed the id of the elementwe want to render.

From File

You can pass the path of a template filelocation like:

$("#foo").html('templates/recipes.ejs',recipeData)

However, you typically want to make thetemplate work from whatever page they are called from. To do this, use // tolook up templates from JMVC root:

$("#foo").html('//app/views/recipes.ejs',recipeData)

Finally, the controller/view plugin can make looking up a thread(and adding helpers) even easier:

$("#foo").html(this.view('recipes', recipeData) )

PackagingTemplates

If you're making heavy use of templates,you want to organize them in files so they can be reused between pages andapplications.

But, this organization would come at ahigh price if the browser has to retrieve each template individually. Theadditional HTTP requests would slow down your app.

Fortunately, [steal.static.viewssteal.views] can build templates into your production files. You just have topoint to the view file like:

steal.views('path/to/the/view.ejs');

Asynchronous

By default, retrieving requests is donesynchronously. This is fine because StealJS packages view templates with yourJS download.

However, some people might not be usingStealJS or want to delay loading templates until necessary. If you have theneed, you can provide a callback paramter like:

$("#foo").html('recipes',recipeData,function(result){

  this.fadeIn()

});

The callback function will be calledwith the result of the rendered template and 'this' will be set to the originaljQuery object.

Deferreds(3.0.6)

If you pass deferreds to $.View or anyof the jQuery modifiers, the view will wait until all deferreds resolve beforerendering the view. This makes it a one-liner to make a request and use theresult to render a template.

The following makes a request for todosin parallel with the todos.ejs template. Once todos and template have beenloaded, it with render the view with the todos.

$('#todos').html("todos.ejs",Todo.findAll());

JustRender Templates

Sometimes, you just want to get theresult of a rendered template without inserting it, you can do this with$.View:

var out =$.View('path/to/template.jaml',{});

PreloadingTemplates

You can preload templates asynchronouslylike:

$.get('path/to/template.jaml',{},function(){},'view');

SupportedTemplate Engines

JavaScriptMVC comes with the followingtemplate languages:

·        EmbeddedJS

<h2><%= message %></h2>

·        JAML

h2(data.message);

·        Micro

<h2>{%= message %}</h2>

·        jQuery.Tmpl

<h2>${message}</h2>

The popular Mustache template engine is supported in a 2ndparty plugin.

Usingother Template Engines

It's easy to integrate your favoritetemplate into $.View and Steal. Read how injQuery.View.register.

Constructor

Looks up a template, processes it,caches it, then renders the template with data and optional helpers.

With StealJS, views are typically bundled in theproduction build. This makes it ok to use views synchronously like:

$.View("//myplugin/views/init.ejs",{message:"Hello World"})

If you aren't using StealJS, it's bestto use views asynchronously like:

$.View("//myplugin/views/init.ejs",

       {message: "Hello World"}, function(result){

  // do something with result

})

new$.View(view, data, helpers, callback) -> String

view {String}

The url or id ofan element to use as the template's source.

data {Object}

The data to bepassed to the view.

helpers {optional:Object}

Optional helperfunctions the view might use. Not all templates support helpers.

callback {optional:Object}

Optionalcallback function. If present, the template is retrieved asynchronously. Thisis a good idea if you aren't compressing the templates into your view.

returns {String}

The renderedresult of the view or if deferreds are passed, a deferred that will resolve tothe rendered result of the view.

 

Language Helperspage

Source

JavaScriptMVC has several lightweightlanguage helper plugins.

Object

Methods useful for comparing Objects.For example, if two objects are the same:

$.Object.same({foo: "bar"}, {foo: "bar"});

Observe

Makes an Object's properties observable:

var person =new $.Observe({ name: "Justin" })

person.bind('change',function(){ ... })

person.attr('name',"Brian");

String

String helpers capitalize, underscore,and perform similar manipulations on strings. They can also lookup a value inan object:

$.String.getObject("foo.bar",{foo:{bar: "car"}})

toJSON

Used to create or consume JSON strings.

Vector

Used for vector math.

 

 

Special Eventspage

Source

JavaScriptMVC provides a bunch of usefulspecial events. Find out more info on the left. The following is a briefsummary:

Default Events

Lets you supply default behavior for anevent that is preventable with event.preventDefault(). This is extremely usefulfor providing DOM-like api's for your widgets.

$("#tabs").delegate(".panel","default.open",function(){

  $(this).show()

})

Destroyed Events

Know if an element has been removed fromthe page.

$("#contextMenu").bind("destroyed",function(){

  // cleanup

 $(document.body).unbind("click.contextMenu");

})

Drag andDrop Events

Listen to drag-drop events with eventdelegation.

$(".item").live("dragover",function(ev, drag){

  // let user know that the item can bedropped

  $(this).addClass("canDrop");

}).live("dropover",function(ev,drop, drag){

  // let user know that the item can bedropped on

  $(this).addClass('drop-able')

})

 

 

原创粉丝点击