5591 lines
306 KiB
HTML
5591 lines
306 KiB
HTML
<!DOCTYPE html>
|
||
|
||
<html>
|
||
<head>
|
||
<title>backbone.js</title>
|
||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;">
|
||
<link rel="stylesheet" media="all" href="docco.css" />
|
||
</head>
|
||
<body>
|
||
<div id="container">
|
||
<div id="background"></div>
|
||
|
||
<ul class="sections">
|
||
|
||
<li id="title">
|
||
<div class="annotation">
|
||
<h1>backbone.js</h1>
|
||
</div>
|
||
</li>
|
||
|
||
|
||
|
||
<li id="section-1">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-1">§</a>
|
||
</div>
|
||
<pre><code><span class="hljs-title class_">Backbone</span>.<span class="hljs-property">js</span> <span class="hljs-number">1.6</span><span class="hljs-number">.0</span>
|
||
</code></pre>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-2">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-2">§</a>
|
||
</div>
|
||
<pre><code>(c) <span class="hljs-number">2010</span>-<span class="hljs-number">2024</span> <span class="hljs-title class_">Jeremy</span> <span class="hljs-title class_">Ashkenas</span> and <span class="hljs-title class_">DocumentCloud</span>
|
||
<span class="hljs-title class_">Backbone</span> may be freely distributed under the <span class="hljs-variable constant_">MIT</span> license.
|
||
<span class="hljs-title class_">For</span> all details and <span class="hljs-attr">documentation</span>:
|
||
<span class="hljs-attr">http</span>:<span class="hljs-comment">//backbonejs.org</span>
|
||
</code></pre>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre>
|
||
(<span class="hljs-keyword">function</span>(<span class="hljs-params">factory</span>) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-3">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-3">§</a>
|
||
</div>
|
||
<p>Establish the root object, <code>window</code> (<code>self</code>) in the browser, or <code>global</code> on the server.
|
||
We use <code>self</code> instead of <code>window</code> for <code>WebWorker</code> support.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> root = <span class="hljs-keyword">typeof</span> self == <span class="hljs-string">'object'</span> && self.<span class="hljs-property">self</span> === self && self ||
|
||
<span class="hljs-keyword">typeof</span> <span class="hljs-variable language_">global</span> == <span class="hljs-string">'object'</span> && <span class="hljs-variable language_">global</span>.<span class="hljs-property">global</span> === <span class="hljs-variable language_">global</span> && <span class="hljs-variable language_">global</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-4">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-4">§</a>
|
||
</div>
|
||
<p>Set up Backbone appropriately for the environment. Start with AMD.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> define === <span class="hljs-string">'function'</span> && define.<span class="hljs-property">amd</span>) {
|
||
<span class="hljs-title function_">define</span>([<span class="hljs-string">'underscore'</span>, <span class="hljs-string">'jquery'</span>, <span class="hljs-string">'exports'</span>], <span class="hljs-keyword">function</span>(<span class="hljs-params">_, $, <span class="hljs-built_in">exports</span></span>) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-5">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-5">§</a>
|
||
</div>
|
||
<p>Export global even in AMD case in case this script is loaded with
|
||
others that may still expect a global Backbone.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> root.<span class="hljs-property">Backbone</span> = <span class="hljs-title function_">factory</span>(root, <span class="hljs-built_in">exports</span>, _, $);
|
||
});</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-6">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-6">§</a>
|
||
</div>
|
||
<p>Next for Node.js or CommonJS. jQuery may not be needed as a module.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> <span class="hljs-built_in">exports</span> !== <span class="hljs-string">'undefined'</span>) {
|
||
<span class="hljs-keyword">var</span> _ = <span class="hljs-built_in">require</span>(<span class="hljs-string">'underscore'</span>), $;
|
||
<span class="hljs-keyword">try</span> { $ = <span class="hljs-built_in">require</span>(<span class="hljs-string">'jquery'</span>); } <span class="hljs-keyword">catch</span> (e) {}
|
||
<span class="hljs-title function_">factory</span>(root, <span class="hljs-built_in">exports</span>, _, $);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-7">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-7">§</a>
|
||
</div>
|
||
<p>Finally, as a browser global.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> } <span class="hljs-keyword">else</span> {
|
||
root.<span class="hljs-property">Backbone</span> = <span class="hljs-title function_">factory</span>(root, {}, root.<span class="hljs-property">_</span>, root.<span class="hljs-property">jQuery</span> || root.<span class="hljs-property">Zepto</span> || root.<span class="hljs-property">ender</span> || root.<span class="hljs-property">$</span>);
|
||
}
|
||
|
||
})(<span class="hljs-keyword">function</span>(<span class="hljs-params">root, Backbone, _, $</span>) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-8">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-8">§</a>
|
||
</div>
|
||
<h2 id="initial-setup">Initial Setup</h2>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-9">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-9">§</a>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-10">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-10">§</a>
|
||
</div>
|
||
<p>Save the previous value of the <code>Backbone</code> variable, so that it can be
|
||
restored later on, if <code>noConflict</code> is used.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> previousBackbone = root.<span class="hljs-property">Backbone</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-11">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-11">§</a>
|
||
</div>
|
||
<p>Create a local reference to a common array method we’ll want to use later.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> slice = <span class="hljs-title class_">Array</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">slice</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-12">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-12">§</a>
|
||
</div>
|
||
<p>Current version of the library. Keep in sync with <code>package.json</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-title class_">Backbone</span>.<span class="hljs-property">VERSION</span> = <span class="hljs-string">'1.6.0'</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-13">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-13">§</a>
|
||
</div>
|
||
<p>For Backbone’s purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
|
||
the <code>$</code> variable.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-title class_">Backbone</span>.<span class="hljs-property">$</span> = $;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-14">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-14">§</a>
|
||
</div>
|
||
<p>Runs Backbone.js in <em>noConflict</em> mode, returning the <code>Backbone</code> variable
|
||
to its previous owner. Returns a reference to this Backbone object.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-title class_">Backbone</span>.<span class="hljs-property">noConflict</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
root.<span class="hljs-property">Backbone</span> = previousBackbone;
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-15">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-15">§</a>
|
||
</div>
|
||
<p>Turn on <code>emulateHTTP</code> to support legacy HTTP servers. Setting this option
|
||
will fake <code>"PATCH"</code>, <code>"PUT"</code> and <code>"DELETE"</code> requests via the <code>_method</code> parameter and
|
||
set a <code>X-Http-Method-Override</code> header.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-title class_">Backbone</span>.<span class="hljs-property">emulateHTTP</span> = <span class="hljs-literal">false</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-16">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-16">§</a>
|
||
</div>
|
||
<p>Turn on <code>emulateJSON</code> to support legacy servers that can’t deal with direct
|
||
<code>application/json</code> requests … this will encode the body as
|
||
<code>application/x-www-form-urlencoded</code> instead and will send the model in a
|
||
form param named <code>model</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-title class_">Backbone</span>.<span class="hljs-property">emulateJSON</span> = <span class="hljs-literal">false</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-17">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-17">§</a>
|
||
</div>
|
||
<h2 id="backboneevents">Backbone.Events</h2>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-18">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-18">§</a>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-19">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-19">§</a>
|
||
</div>
|
||
<p>A module that can be mixed in to <em>any object</em> in order to provide it with
|
||
a custom event channel. You may bind a callback to an event with <code>on</code> or
|
||
remove with <code>off</code>; <code>trigger</code>-ing an event fires all callbacks in
|
||
succession.</p>
|
||
<pre><code><span class="hljs-keyword">var</span> object = {};
|
||
_.<span class="hljs-title function_">extend</span>(object, <span class="hljs-title class_">Backbone</span>.<span class="hljs-property">Events</span>);
|
||
object.<span class="hljs-title function_">on</span>(<span class="hljs-string">'expand'</span>, <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){ <span class="hljs-title function_">alert</span>(<span class="hljs-string">'expanded'</span>); });
|
||
object.<span class="hljs-title function_">trigger</span>(<span class="hljs-string">'expand'</span>);
|
||
</code></pre>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> <span class="hljs-title class_">Events</span> = <span class="hljs-title class_">Backbone</span>.<span class="hljs-property">Events</span> = {};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-20">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-20">§</a>
|
||
</div>
|
||
<p>Regular expression used to split event strings.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> eventSplitter = <span class="hljs-regexp">/\s+/</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-21">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-21">§</a>
|
||
</div>
|
||
<p>A private global variable to share between listeners and listenees.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> _listening;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-22">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-22">§</a>
|
||
</div>
|
||
<p>Iterates over the standard <code>event, callback</code> (as well as the fancy multiple
|
||
space-separated events <code>"change blur", callback</code> and jQuery-style event
|
||
maps <code>{event: callback}</code>).</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> eventsApi = <span class="hljs-keyword">function</span>(<span class="hljs-params">iteratee, events, name, callback, opts</span>) {
|
||
<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>, names;
|
||
<span class="hljs-keyword">if</span> (name && <span class="hljs-keyword">typeof</span> name === <span class="hljs-string">'object'</span>) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-23">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-23">§</a>
|
||
</div>
|
||
<p>Handle event maps.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (callback !== <span class="hljs-keyword">void</span> <span class="hljs-number">0</span> && <span class="hljs-string">'context'</span> <span class="hljs-keyword">in</span> opts && opts.<span class="hljs-property">context</span> === <span class="hljs-keyword">void</span> <span class="hljs-number">0</span>) opts.<span class="hljs-property">context</span> = callback;
|
||
<span class="hljs-keyword">for</span> (names = _.<span class="hljs-title function_">keys</span>(name); i < names.<span class="hljs-property">length</span> ; i++) {
|
||
events = <span class="hljs-title function_">eventsApi</span>(iteratee, events, names[i], name[names[i]], opts);
|
||
}
|
||
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (name && eventSplitter.<span class="hljs-title function_">test</span>(name)) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-24">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-24">§</a>
|
||
</div>
|
||
<p>Handle space-separated event names by delegating them individually.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (names = name.<span class="hljs-title function_">split</span>(eventSplitter); i < names.<span class="hljs-property">length</span>; i++) {
|
||
events = <span class="hljs-title function_">iteratee</span>(events, names[i], callback, opts);
|
||
}
|
||
} <span class="hljs-keyword">else</span> {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-25">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-25">§</a>
|
||
</div>
|
||
<p>Finally, standard events.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> events = <span class="hljs-title function_">iteratee</span>(events, name, callback, opts);
|
||
}
|
||
<span class="hljs-keyword">return</span> events;
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-26">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-26">§</a>
|
||
</div>
|
||
<p>Bind an event to a <code>callback</code> function. Passing <code>"all"</code> will bind
|
||
the callback to all events fired.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-title class_">Events</span>.<span class="hljs-property">on</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">name, callback, context</span>) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_events</span> = <span class="hljs-title function_">eventsApi</span>(onApi, <span class="hljs-variable language_">this</span>.<span class="hljs-property">_events</span> || {}, name, callback, {
|
||
<span class="hljs-attr">context</span>: context,
|
||
<span class="hljs-attr">ctx</span>: <span class="hljs-variable language_">this</span>,
|
||
<span class="hljs-attr">listening</span>: _listening
|
||
});
|
||
|
||
<span class="hljs-keyword">if</span> (_listening) {
|
||
<span class="hljs-keyword">var</span> listeners = <span class="hljs-variable language_">this</span>.<span class="hljs-property">_listeners</span> || (<span class="hljs-variable language_">this</span>.<span class="hljs-property">_listeners</span> = {});
|
||
listeners[_listening.<span class="hljs-property">id</span>] = _listening;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-27">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-27">§</a>
|
||
</div>
|
||
<p>Allow the listening to use a counter, instead of tracking
|
||
callbacks for library interop</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _listening.<span class="hljs-property">interop</span> = <span class="hljs-literal">false</span>;
|
||
}
|
||
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-28">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-28">§</a>
|
||
</div>
|
||
<p>Inversion-of-control versions of <code>on</code>. Tell <em>this</em> object to listen to
|
||
an event in another object… keeping track of what it’s listening to
|
||
for easier unbinding later.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-title class_">Events</span>.<span class="hljs-property">listenTo</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">obj, name, callback</span>) {
|
||
<span class="hljs-keyword">if</span> (!obj) <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
<span class="hljs-keyword">var</span> id = obj.<span class="hljs-property">_listenId</span> || (obj.<span class="hljs-property">_listenId</span> = _.<span class="hljs-title function_">uniqueId</span>(<span class="hljs-string">'l'</span>));
|
||
<span class="hljs-keyword">var</span> listeningTo = <span class="hljs-variable language_">this</span>.<span class="hljs-property">_listeningTo</span> || (<span class="hljs-variable language_">this</span>.<span class="hljs-property">_listeningTo</span> = {});
|
||
<span class="hljs-keyword">var</span> listening = _listening = listeningTo[id];</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-29">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-29">§</a>
|
||
</div>
|
||
<p>This object is not listening to any other events on <code>obj</code> yet.
|
||
Setup the necessary references to track the listening callbacks.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!listening) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_listenId</span> || (<span class="hljs-variable language_">this</span>.<span class="hljs-property">_listenId</span> = _.<span class="hljs-title function_">uniqueId</span>(<span class="hljs-string">'l'</span>));
|
||
listening = _listening = listeningTo[id] = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Listening</span>(<span class="hljs-variable language_">this</span>, obj);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-30">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-30">§</a>
|
||
</div>
|
||
<p>Bind callbacks on obj.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> error = <span class="hljs-title function_">tryCatchOn</span>(obj, name, callback, <span class="hljs-variable language_">this</span>);
|
||
_listening = <span class="hljs-keyword">void</span> <span class="hljs-number">0</span>;
|
||
|
||
<span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">throw</span> error;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-31">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-31">§</a>
|
||
</div>
|
||
<p>If the target obj is not Backbone.Events, track events manually.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (listening.<span class="hljs-property">interop</span>) listening.<span class="hljs-title function_">on</span>(name, callback);
|
||
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-32">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-32">§</a>
|
||
</div>
|
||
<p>The reducing API that adds a callback to the <code>events</code> object.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> onApi = <span class="hljs-keyword">function</span>(<span class="hljs-params">events, name, callback, options</span>) {
|
||
<span class="hljs-keyword">if</span> (callback) {
|
||
<span class="hljs-keyword">var</span> handlers = events[name] || (events[name] = []);
|
||
<span class="hljs-keyword">var</span> context = options.<span class="hljs-property">context</span>, ctx = options.<span class="hljs-property">ctx</span>, listening = options.<span class="hljs-property">listening</span>;
|
||
<span class="hljs-keyword">if</span> (listening) listening.<span class="hljs-property">count</span>++;
|
||
|
||
handlers.<span class="hljs-title function_">push</span>({<span class="hljs-attr">callback</span>: callback, <span class="hljs-attr">context</span>: context, <span class="hljs-attr">ctx</span>: context || ctx, <span class="hljs-attr">listening</span>: listening});
|
||
}
|
||
<span class="hljs-keyword">return</span> events;
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-33">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-33">§</a>
|
||
</div>
|
||
<p>An try-catch guarded #on function, to prevent poisoning the global
|
||
<code>_listening</code> variable.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> tryCatchOn = <span class="hljs-keyword">function</span>(<span class="hljs-params">obj, name, callback, context</span>) {
|
||
<span class="hljs-keyword">try</span> {
|
||
obj.<span class="hljs-title function_">on</span>(name, callback, context);
|
||
} <span class="hljs-keyword">catch</span> (e) {
|
||
<span class="hljs-keyword">return</span> e;
|
||
}
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-34">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-34">§</a>
|
||
</div>
|
||
<p>Remove one or many callbacks. If <code>context</code> is null, removes all
|
||
callbacks with that function. If <code>callback</code> is null, removes all
|
||
callbacks for the event. If <code>name</code> is null, removes all bound
|
||
callbacks for all events.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-title class_">Events</span>.<span class="hljs-property">off</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">name, callback, context</span>) {
|
||
<span class="hljs-keyword">if</span> (!<span class="hljs-variable language_">this</span>.<span class="hljs-property">_events</span>) <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_events</span> = <span class="hljs-title function_">eventsApi</span>(offApi, <span class="hljs-variable language_">this</span>.<span class="hljs-property">_events</span>, name, callback, {
|
||
<span class="hljs-attr">context</span>: context,
|
||
<span class="hljs-attr">listeners</span>: <span class="hljs-variable language_">this</span>.<span class="hljs-property">_listeners</span>
|
||
});
|
||
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-35">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-35">§</a>
|
||
</div>
|
||
<p>Tell this object to stop listening to either specific events … or
|
||
to every object it’s currently listening to.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-title class_">Events</span>.<span class="hljs-property">stopListening</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">obj, name, callback</span>) {
|
||
<span class="hljs-keyword">var</span> listeningTo = <span class="hljs-variable language_">this</span>.<span class="hljs-property">_listeningTo</span>;
|
||
<span class="hljs-keyword">if</span> (!listeningTo) <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
|
||
<span class="hljs-keyword">var</span> ids = obj ? [obj.<span class="hljs-property">_listenId</span>] : _.<span class="hljs-title function_">keys</span>(listeningTo);
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < ids.<span class="hljs-property">length</span>; i++) {
|
||
<span class="hljs-keyword">var</span> listening = listeningTo[ids[i]];</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-36">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-36">§</a>
|
||
</div>
|
||
<p>If listening doesn’t exist, this object is not currently
|
||
listening to obj. Break out early.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!listening) <span class="hljs-keyword">break</span>;
|
||
|
||
listening.<span class="hljs-property">obj</span>.<span class="hljs-title function_">off</span>(name, callback, <span class="hljs-variable language_">this</span>);
|
||
<span class="hljs-keyword">if</span> (listening.<span class="hljs-property">interop</span>) listening.<span class="hljs-title function_">off</span>(name, callback);
|
||
}
|
||
<span class="hljs-keyword">if</span> (_.<span class="hljs-title function_">isEmpty</span>(listeningTo)) <span class="hljs-variable language_">this</span>.<span class="hljs-property">_listeningTo</span> = <span class="hljs-keyword">void</span> <span class="hljs-number">0</span>;
|
||
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-37">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-37">§</a>
|
||
</div>
|
||
<p>The reducing API that removes a callback from the <code>events</code> object.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> offApi = <span class="hljs-keyword">function</span>(<span class="hljs-params">events, name, callback, options</span>) {
|
||
<span class="hljs-keyword">if</span> (!events) <span class="hljs-keyword">return</span>;
|
||
|
||
<span class="hljs-keyword">var</span> context = options.<span class="hljs-property">context</span>, listeners = options.<span class="hljs-property">listeners</span>;
|
||
<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>, names;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-38">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-38">§</a>
|
||
</div>
|
||
<p>Delete all event listeners and “drop” events.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!name && !context && !callback) {
|
||
<span class="hljs-keyword">for</span> (names = _.<span class="hljs-title function_">keys</span>(listeners); i < names.<span class="hljs-property">length</span>; i++) {
|
||
listeners[names[i]].<span class="hljs-title function_">cleanup</span>();
|
||
}
|
||
<span class="hljs-keyword">return</span>;
|
||
}
|
||
|
||
names = name ? [name] : _.<span class="hljs-title function_">keys</span>(events);
|
||
<span class="hljs-keyword">for</span> (; i < names.<span class="hljs-property">length</span>; i++) {
|
||
name = names[i];
|
||
<span class="hljs-keyword">var</span> handlers = events[name];</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-39">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-39">§</a>
|
||
</div>
|
||
<p>Bail out if there are no events stored.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!handlers) <span class="hljs-keyword">break</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-40">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-40">§</a>
|
||
</div>
|
||
<p>Find any remaining events.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> remaining = [];
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> j = <span class="hljs-number">0</span>; j < handlers.<span class="hljs-property">length</span>; j++) {
|
||
<span class="hljs-keyword">var</span> handler = handlers[j];
|
||
<span class="hljs-keyword">if</span> (
|
||
callback && callback !== handler.<span class="hljs-property">callback</span> &&
|
||
callback !== handler.<span class="hljs-property">callback</span>.<span class="hljs-property">_callback</span> ||
|
||
context && context !== handler.<span class="hljs-property">context</span>
|
||
) {
|
||
remaining.<span class="hljs-title function_">push</span>(handler);
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-keyword">var</span> listening = handler.<span class="hljs-property">listening</span>;
|
||
<span class="hljs-keyword">if</span> (listening) listening.<span class="hljs-title function_">off</span>(name, callback);
|
||
}
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-41">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-41">§</a>
|
||
</div>
|
||
<p>Replace events if there are any remaining. Otherwise, clean up.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (remaining.<span class="hljs-property">length</span>) {
|
||
events[name] = remaining;
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-keyword">delete</span> events[name];
|
||
}
|
||
}
|
||
|
||
<span class="hljs-keyword">return</span> events;
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-42">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-42">§</a>
|
||
</div>
|
||
<p>Bind an event to only be triggered a single time. After the first time
|
||
the callback is invoked, its listener will be removed. If multiple events
|
||
are passed in using the space-separated syntax, the handler will fire
|
||
once for each event, not once for a combination of all events.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-title class_">Events</span>.<span class="hljs-property">once</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">name, callback, context</span>) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-43">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-43">§</a>
|
||
</div>
|
||
<p>Map the event into a <code>{event: once}</code> object.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> events = <span class="hljs-title function_">eventsApi</span>(onceMap, {}, name, callback, <span class="hljs-variable language_">this</span>.<span class="hljs-property">off</span>.<span class="hljs-title function_">bind</span>(<span class="hljs-variable language_">this</span>));
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> name === <span class="hljs-string">'string'</span> && context == <span class="hljs-literal">null</span>) callback = <span class="hljs-keyword">void</span> <span class="hljs-number">0</span>;
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">on</span>(events, callback, context);
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-44">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-44">§</a>
|
||
</div>
|
||
<p>Inversion-of-control versions of <code>once</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-title class_">Events</span>.<span class="hljs-property">listenToOnce</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">obj, name, callback</span>) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-45">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-45">§</a>
|
||
</div>
|
||
<p>Map the event into a <code>{event: once}</code> object.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> events = <span class="hljs-title function_">eventsApi</span>(onceMap, {}, name, callback, <span class="hljs-variable language_">this</span>.<span class="hljs-property">stopListening</span>.<span class="hljs-title function_">bind</span>(<span class="hljs-variable language_">this</span>, obj));
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">listenTo</span>(obj, events);
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-46">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-46">§</a>
|
||
</div>
|
||
<p>Reduces the event callbacks into a map of <code>{event: onceWrapper}</code>.
|
||
<code>offer</code> unbinds the <code>onceWrapper</code> after it has been called.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> onceMap = <span class="hljs-keyword">function</span>(<span class="hljs-params">map, name, callback, offer</span>) {
|
||
<span class="hljs-keyword">if</span> (callback) {
|
||
<span class="hljs-keyword">var</span> once = map[name] = _.<span class="hljs-title function_">once</span>(<span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-title function_">offer</span>(name, once);
|
||
callback.<span class="hljs-title function_">apply</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-variable language_">arguments</span>);
|
||
});
|
||
once.<span class="hljs-property">_callback</span> = callback;
|
||
}
|
||
<span class="hljs-keyword">return</span> map;
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-47">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-47">§</a>
|
||
</div>
|
||
<p>Trigger one or many events, firing all bound callbacks. Callbacks are
|
||
passed the same arguments as <code>trigger</code> is, apart from the event name
|
||
(unless you’re listening on <code>"all"</code>, which will cause your callback to
|
||
receive the true name of the event as the first argument).</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-title class_">Events</span>.<span class="hljs-property">trigger</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">name</span>) {
|
||
<span class="hljs-keyword">if</span> (!<span class="hljs-variable language_">this</span>.<span class="hljs-property">_events</span>) <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
|
||
<span class="hljs-keyword">var</span> length = <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">max</span>(<span class="hljs-number">0</span>, <span class="hljs-variable language_">arguments</span>.<span class="hljs-property">length</span> - <span class="hljs-number">1</span>);
|
||
<span class="hljs-keyword">var</span> args = <span class="hljs-title class_">Array</span>(length);
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < length; i++) args[i] = <span class="hljs-variable language_">arguments</span>[i + <span class="hljs-number">1</span>];
|
||
|
||
<span class="hljs-title function_">eventsApi</span>(triggerApi, <span class="hljs-variable language_">this</span>.<span class="hljs-property">_events</span>, name, <span class="hljs-keyword">void</span> <span class="hljs-number">0</span>, args);
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-48">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-48">§</a>
|
||
</div>
|
||
<p>Handles triggering the appropriate event callbacks.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> triggerApi = <span class="hljs-keyword">function</span>(<span class="hljs-params">objEvents, name, callback, args</span>) {
|
||
<span class="hljs-keyword">if</span> (objEvents) {
|
||
<span class="hljs-keyword">var</span> events = objEvents[name];
|
||
<span class="hljs-keyword">var</span> allEvents = objEvents.<span class="hljs-property">all</span>;
|
||
<span class="hljs-keyword">if</span> (events && allEvents) allEvents = allEvents.<span class="hljs-title function_">slice</span>();
|
||
<span class="hljs-keyword">if</span> (events) <span class="hljs-title function_">triggerEvents</span>(events, args);
|
||
<span class="hljs-keyword">if</span> (allEvents) <span class="hljs-title function_">triggerEvents</span>(allEvents, [name].<span class="hljs-title function_">concat</span>(args));
|
||
}
|
||
<span class="hljs-keyword">return</span> objEvents;
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-49">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-49">§</a>
|
||
</div>
|
||
<p>A difficult-to-believe, but optimized internal dispatch function for
|
||
triggering events. Tries to keep the usual cases speedy (most internal
|
||
Backbone events have 3 arguments).</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> triggerEvents = <span class="hljs-keyword">function</span>(<span class="hljs-params">events, args</span>) {
|
||
<span class="hljs-keyword">var</span> ev, i = -<span class="hljs-number">1</span>, l = events.<span class="hljs-property">length</span>, a1 = args[<span class="hljs-number">0</span>], a2 = args[<span class="hljs-number">1</span>], a3 = args[<span class="hljs-number">2</span>];
|
||
<span class="hljs-keyword">switch</span> (args.<span class="hljs-property">length</span>) {
|
||
<span class="hljs-keyword">case</span> <span class="hljs-number">0</span>: <span class="hljs-keyword">while</span> (++i < l) (ev = events[i]).<span class="hljs-property">callback</span>.<span class="hljs-title function_">call</span>(ev.<span class="hljs-property">ctx</span>); <span class="hljs-keyword">return</span>;
|
||
<span class="hljs-keyword">case</span> <span class="hljs-number">1</span>: <span class="hljs-keyword">while</span> (++i < l) (ev = events[i]).<span class="hljs-property">callback</span>.<span class="hljs-title function_">call</span>(ev.<span class="hljs-property">ctx</span>, a1); <span class="hljs-keyword">return</span>;
|
||
<span class="hljs-keyword">case</span> <span class="hljs-number">2</span>: <span class="hljs-keyword">while</span> (++i < l) (ev = events[i]).<span class="hljs-property">callback</span>.<span class="hljs-title function_">call</span>(ev.<span class="hljs-property">ctx</span>, a1, a2); <span class="hljs-keyword">return</span>;
|
||
<span class="hljs-keyword">case</span> <span class="hljs-number">3</span>: <span class="hljs-keyword">while</span> (++i < l) (ev = events[i]).<span class="hljs-property">callback</span>.<span class="hljs-title function_">call</span>(ev.<span class="hljs-property">ctx</span>, a1, a2, a3); <span class="hljs-keyword">return</span>;
|
||
<span class="hljs-attr">default</span>: <span class="hljs-keyword">while</span> (++i < l) (ev = events[i]).<span class="hljs-property">callback</span>.<span class="hljs-title function_">apply</span>(ev.<span class="hljs-property">ctx</span>, args); <span class="hljs-keyword">return</span>;
|
||
}
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-50">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-50">§</a>
|
||
</div>
|
||
<p>A listening class that tracks and cleans up memory bindings
|
||
when all callbacks have been offed.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> <span class="hljs-title class_">Listening</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">listener, obj</span>) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">id</span> = listener.<span class="hljs-property">_listenId</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">listener</span> = listener;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">obj</span> = obj;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">interop</span> = <span class="hljs-literal">true</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">count</span> = <span class="hljs-number">0</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_events</span> = <span class="hljs-keyword">void</span> <span class="hljs-number">0</span>;
|
||
};
|
||
|
||
<span class="hljs-title class_">Listening</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">on</span> = <span class="hljs-title class_">Events</span>.<span class="hljs-property">on</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-51">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-51">§</a>
|
||
</div>
|
||
<p>Offs a callback (or several).
|
||
Uses an optimized counter if the listenee uses Backbone.Events.
|
||
Otherwise, falls back to manual tracking to support events
|
||
library interop.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-title class_">Listening</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">off</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">name, callback</span>) {
|
||
<span class="hljs-keyword">var</span> cleanup;
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">interop</span>) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_events</span> = <span class="hljs-title function_">eventsApi</span>(offApi, <span class="hljs-variable language_">this</span>.<span class="hljs-property">_events</span>, name, callback, {
|
||
<span class="hljs-attr">context</span>: <span class="hljs-keyword">void</span> <span class="hljs-number">0</span>,
|
||
<span class="hljs-attr">listeners</span>: <span class="hljs-keyword">void</span> <span class="hljs-number">0</span>
|
||
});
|
||
cleanup = !<span class="hljs-variable language_">this</span>.<span class="hljs-property">_events</span>;
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">count</span>--;
|
||
cleanup = <span class="hljs-variable language_">this</span>.<span class="hljs-property">count</span> === <span class="hljs-number">0</span>;
|
||
}
|
||
<span class="hljs-keyword">if</span> (cleanup) <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">cleanup</span>();
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-52">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-52">§</a>
|
||
</div>
|
||
<p>Cleans up memory bindings between the listener and the listenee.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-title class_">Listening</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">cleanup</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">delete</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">listener</span>.<span class="hljs-property">_listeningTo</span>[<span class="hljs-variable language_">this</span>.<span class="hljs-property">obj</span>.<span class="hljs-property">_listenId</span>];
|
||
<span class="hljs-keyword">if</span> (!<span class="hljs-variable language_">this</span>.<span class="hljs-property">interop</span>) <span class="hljs-keyword">delete</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">obj</span>.<span class="hljs-property">_listeners</span>[<span class="hljs-variable language_">this</span>.<span class="hljs-property">id</span>];
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-53">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-53">§</a>
|
||
</div>
|
||
<p>Aliases for backwards compatibility.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-title class_">Events</span>.<span class="hljs-property">bind</span> = <span class="hljs-title class_">Events</span>.<span class="hljs-property">on</span>;
|
||
<span class="hljs-title class_">Events</span>.<span class="hljs-property">unbind</span> = <span class="hljs-title class_">Events</span>.<span class="hljs-property">off</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-54">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-54">§</a>
|
||
</div>
|
||
<p>Allow the <code>Backbone</code> object to serve as a global event bus, for folks who
|
||
want global “pubsub” in a convenient place.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _.<span class="hljs-title function_">extend</span>(<span class="hljs-title class_">Backbone</span>, <span class="hljs-title class_">Events</span>);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-55">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-55">§</a>
|
||
</div>
|
||
<h2 id="backbonemodel">Backbone.Model</h2>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-56">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-56">§</a>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-57">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-57">§</a>
|
||
</div>
|
||
<p>Backbone <strong>Models</strong> are the basic data object in the framework –
|
||
frequently representing a row in a table in a database on your server.
|
||
A discrete chunk of data and a bunch of useful, related methods for
|
||
performing computations and transformations on that data.</p>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-58">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-58">§</a>
|
||
</div>
|
||
<p>Create a new model with the specified attributes. A client id (<code>cid</code>)
|
||
is automatically generated and assigned for you.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> <span class="hljs-title class_">Model</span> = <span class="hljs-title class_">Backbone</span>.<span class="hljs-property">Model</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">attributes, options</span>) {
|
||
<span class="hljs-keyword">var</span> attrs = attributes || {};
|
||
options || (options = {});
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">preinitialize</span>.<span class="hljs-title function_">apply</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-variable language_">arguments</span>);
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">cid</span> = _.<span class="hljs-title function_">uniqueId</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">cidPrefix</span>);
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">attributes</span> = {};
|
||
<span class="hljs-keyword">if</span> (options.<span class="hljs-property">collection</span>) <span class="hljs-variable language_">this</span>.<span class="hljs-property">collection</span> = options.<span class="hljs-property">collection</span>;
|
||
<span class="hljs-keyword">if</span> (options.<span class="hljs-property">parse</span>) attrs = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">parse</span>(attrs, options) || {};
|
||
<span class="hljs-keyword">var</span> defaults = _.<span class="hljs-title function_">result</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-string">'defaults'</span>);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-59">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-59">§</a>
|
||
</div>
|
||
<p>Just _.defaults would work fine, but the additional _.extends
|
||
is in there for historical reasons. See #3843.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> attrs = _.<span class="hljs-title function_">defaults</span>(_.<span class="hljs-title function_">extend</span>({}, defaults, attrs), defaults);
|
||
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">set</span>(attrs, options);
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">changed</span> = {};
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">initialize</span>.<span class="hljs-title function_">apply</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-variable language_">arguments</span>);
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-60">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-60">§</a>
|
||
</div>
|
||
<p>Attach all inheritable methods to the Model prototype.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _.<span class="hljs-title function_">extend</span>(<span class="hljs-title class_">Model</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>, <span class="hljs-title class_">Events</span>, {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-61">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-61">§</a>
|
||
</div>
|
||
<p>A hash of attributes whose current and previous value differ.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">changed</span>: <span class="hljs-literal">null</span>,</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-62">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-62">§</a>
|
||
</div>
|
||
<p>The value returned during the last failed validation.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">validationError</span>: <span class="hljs-literal">null</span>,</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-63">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-63">§</a>
|
||
</div>
|
||
<p>The default name for the JSON <code>id</code> attribute is <code>"id"</code>. MongoDB and
|
||
CouchDB users may want to set this to <code>"_id"</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">idAttribute</span>: <span class="hljs-string">'id'</span>,</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-64">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-64">§</a>
|
||
</div>
|
||
<p>The prefix is used to create the client id which is used to identify models locally.
|
||
You may want to override this if you’re experiencing name clashes with model ids.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">cidPrefix</span>: <span class="hljs-string">'c'</span>,</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-65">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-65">§</a>
|
||
</div>
|
||
<p>preinitialize is an empty function by default. You can override it with a function
|
||
or object. preinitialize will run before any instantiation logic is run in the Model.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">preinitialize</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-66">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-66">§</a>
|
||
</div>
|
||
<p>Initialize is an empty function by default. Override it with your own
|
||
initialization logic.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">initialize</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-67">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-67">§</a>
|
||
</div>
|
||
<p>Return a copy of the model’s <code>attributes</code> object.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">toJSON</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">options</span>) {
|
||
<span class="hljs-keyword">return</span> _.<span class="hljs-title function_">clone</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">attributes</span>);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-68">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-68">§</a>
|
||
</div>
|
||
<p>Proxy <code>Backbone.sync</code> by default – but override this if you need
|
||
custom syncing semantics for <em>this</em> particular model.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">sync</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-title class_">Backbone</span>.<span class="hljs-property">sync</span>.<span class="hljs-title function_">apply</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-variable language_">arguments</span>);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-69">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-69">§</a>
|
||
</div>
|
||
<p>Get the value of an attribute.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">get</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">attr</span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">attributes</span>[attr];
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-70">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-70">§</a>
|
||
</div>
|
||
<p>Get the HTML-escaped value of an attribute.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">escape</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">attr</span>) {
|
||
<span class="hljs-keyword">return</span> _.<span class="hljs-built_in">escape</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">get</span>(attr));
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-71">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-71">§</a>
|
||
</div>
|
||
<p>Returns <code>true</code> if the attribute contains a value that is not null
|
||
or undefined.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">has</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">attr</span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">get</span>(attr) != <span class="hljs-literal">null</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-72">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-72">§</a>
|
||
</div>
|
||
<p>Special-cased proxy to underscore’s <code>_.matches</code> method.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">matches</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">attrs</span>) {
|
||
<span class="hljs-keyword">return</span> !!_.<span class="hljs-title function_">iteratee</span>(attrs, <span class="hljs-variable language_">this</span>)(<span class="hljs-variable language_">this</span>.<span class="hljs-property">attributes</span>);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-73">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-73">§</a>
|
||
</div>
|
||
<p>Set a hash of model attributes on the object, firing <code>"change"</code>. This is
|
||
the core primitive operation of a model, updating the data and notifying
|
||
anyone who needs to know about the change in state. The heart of the beast.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">set</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">key, val, options</span>) {
|
||
<span class="hljs-keyword">if</span> (key == <span class="hljs-literal">null</span>) <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-74">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-74">§</a>
|
||
</div>
|
||
<p>Handle both <code>"key", value</code> and <code>{key: value}</code> -style arguments.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> attrs;
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> key === <span class="hljs-string">'object'</span>) {
|
||
attrs = key;
|
||
options = val;
|
||
} <span class="hljs-keyword">else</span> {
|
||
(attrs = {})[key] = val;
|
||
}
|
||
|
||
options || (options = {});</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-75">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-75">§</a>
|
||
</div>
|
||
<p>Run validation.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_validate</span>(attrs, options)) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-76">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-76">§</a>
|
||
</div>
|
||
<p>Extract attributes and options.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> unset = options.<span class="hljs-property">unset</span>;
|
||
<span class="hljs-keyword">var</span> silent = options.<span class="hljs-property">silent</span>;
|
||
<span class="hljs-keyword">var</span> changes = [];
|
||
<span class="hljs-keyword">var</span> changing = <span class="hljs-variable language_">this</span>.<span class="hljs-property">_changing</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_changing</span> = <span class="hljs-literal">true</span>;
|
||
|
||
<span class="hljs-keyword">if</span> (!changing) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_previousAttributes</span> = _.<span class="hljs-title function_">clone</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">attributes</span>);
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">changed</span> = {};
|
||
}
|
||
|
||
<span class="hljs-keyword">var</span> current = <span class="hljs-variable language_">this</span>.<span class="hljs-property">attributes</span>;
|
||
<span class="hljs-keyword">var</span> changed = <span class="hljs-variable language_">this</span>.<span class="hljs-property">changed</span>;
|
||
<span class="hljs-keyword">var</span> prev = <span class="hljs-variable language_">this</span>.<span class="hljs-property">_previousAttributes</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-77">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-77">§</a>
|
||
</div>
|
||
<p>For each <code>set</code> attribute, update or delete the current value.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> attr <span class="hljs-keyword">in</span> attrs) {
|
||
val = attrs[attr];
|
||
<span class="hljs-keyword">if</span> (!_.<span class="hljs-title function_">isEqual</span>(current[attr], val)) changes.<span class="hljs-title function_">push</span>(attr);
|
||
<span class="hljs-keyword">if</span> (!_.<span class="hljs-title function_">isEqual</span>(prev[attr], val)) {
|
||
changed[attr] = val;
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-keyword">delete</span> changed[attr];
|
||
}
|
||
unset ? <span class="hljs-keyword">delete</span> current[attr] : current[attr] = val;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-78">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-78">§</a>
|
||
</div>
|
||
<p>Update the <code>id</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">idAttribute</span> <span class="hljs-keyword">in</span> attrs) {
|
||
<span class="hljs-keyword">var</span> prevId = <span class="hljs-variable language_">this</span>.<span class="hljs-property">id</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">id</span> = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">get</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">idAttribute</span>);
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">trigger</span>(<span class="hljs-string">'changeId'</span>, <span class="hljs-variable language_">this</span>, prevId, options);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-79">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-79">§</a>
|
||
</div>
|
||
<p>Trigger all relevant attribute changes.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!silent) {
|
||
<span class="hljs-keyword">if</span> (changes.<span class="hljs-property">length</span>) <span class="hljs-variable language_">this</span>.<span class="hljs-property">_pending</span> = options;
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < changes.<span class="hljs-property">length</span>; i++) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">trigger</span>(<span class="hljs-string">'change:'</span> + changes[i], <span class="hljs-variable language_">this</span>, current[changes[i]], options);
|
||
}
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-80">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-80">§</a>
|
||
</div>
|
||
<p>You might be wondering why there’s a <code>while</code> loop here. Changes can
|
||
be recursively nested within <code>"change"</code> events.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (changing) <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
<span class="hljs-keyword">if</span> (!silent) {
|
||
<span class="hljs-keyword">while</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">_pending</span>) {
|
||
options = <span class="hljs-variable language_">this</span>.<span class="hljs-property">_pending</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_pending</span> = <span class="hljs-literal">false</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">trigger</span>(<span class="hljs-string">'change'</span>, <span class="hljs-variable language_">this</span>, options);
|
||
}
|
||
}
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_pending</span> = <span class="hljs-literal">false</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_changing</span> = <span class="hljs-literal">false</span>;
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-81">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-81">§</a>
|
||
</div>
|
||
<p>Remove an attribute from the model, firing <code>"change"</code>. <code>unset</code> is a noop
|
||
if the attribute doesn’t exist.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">unset</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">attr, options</span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">set</span>(attr, <span class="hljs-keyword">void</span> <span class="hljs-number">0</span>, _.<span class="hljs-title function_">extend</span>({}, options, {<span class="hljs-attr">unset</span>: <span class="hljs-literal">true</span>}));
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-82">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-82">§</a>
|
||
</div>
|
||
<p>Clear all attributes on the model, firing <code>"change"</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">clear</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">options</span>) {
|
||
<span class="hljs-keyword">var</span> attrs = {};
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> key <span class="hljs-keyword">in</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">attributes</span>) attrs[key] = <span class="hljs-keyword">void</span> <span class="hljs-number">0</span>;
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">set</span>(attrs, _.<span class="hljs-title function_">extend</span>({}, options, {<span class="hljs-attr">unset</span>: <span class="hljs-literal">true</span>}));
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-83">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-83">§</a>
|
||
</div>
|
||
<p>Determine if the model has changed since the last <code>"change"</code> event.
|
||
If you specify an attribute name, determine if that attribute has changed.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">hasChanged</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">attr</span>) {
|
||
<span class="hljs-keyword">if</span> (attr == <span class="hljs-literal">null</span>) <span class="hljs-keyword">return</span> !_.<span class="hljs-title function_">isEmpty</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">changed</span>);
|
||
<span class="hljs-keyword">return</span> _.<span class="hljs-title function_">has</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">changed</span>, attr);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-84">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-84">§</a>
|
||
</div>
|
||
<p>Return an object containing all the attributes that have changed, or
|
||
false if there are no changed attributes. Useful for determining what
|
||
parts of a view need to be updated and/or what attributes need to be
|
||
persisted to the server. Unset attributes will be set to undefined.
|
||
You can also pass an attributes object to diff against the model,
|
||
determining if there <em>would be</em> a change.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">changedAttributes</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">diff</span>) {
|
||
<span class="hljs-keyword">if</span> (!diff) <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">hasChanged</span>() ? _.<span class="hljs-title function_">clone</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">changed</span>) : <span class="hljs-literal">false</span>;
|
||
<span class="hljs-keyword">var</span> old = <span class="hljs-variable language_">this</span>.<span class="hljs-property">_changing</span> ? <span class="hljs-variable language_">this</span>.<span class="hljs-property">_previousAttributes</span> : <span class="hljs-variable language_">this</span>.<span class="hljs-property">attributes</span>;
|
||
<span class="hljs-keyword">var</span> changed = {};
|
||
<span class="hljs-keyword">var</span> hasChanged;
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> attr <span class="hljs-keyword">in</span> diff) {
|
||
<span class="hljs-keyword">var</span> val = diff[attr];
|
||
<span class="hljs-keyword">if</span> (_.<span class="hljs-title function_">isEqual</span>(old[attr], val)) <span class="hljs-keyword">continue</span>;
|
||
changed[attr] = val;
|
||
hasChanged = <span class="hljs-literal">true</span>;
|
||
}
|
||
<span class="hljs-keyword">return</span> hasChanged ? changed : <span class="hljs-literal">false</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-85">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-85">§</a>
|
||
</div>
|
||
<p>Get the previous value of an attribute, recorded at the time the last
|
||
<code>"change"</code> event was fired.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">previous</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">attr</span>) {
|
||
<span class="hljs-keyword">if</span> (attr == <span class="hljs-literal">null</span> || !<span class="hljs-variable language_">this</span>.<span class="hljs-property">_previousAttributes</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">_previousAttributes</span>[attr];
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-86">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-86">§</a>
|
||
</div>
|
||
<p>Get all of the attributes of the model at the time of the previous
|
||
<code>"change"</code> event.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">previousAttributes</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">return</span> _.<span class="hljs-title function_">clone</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">_previousAttributes</span>);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-87">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-87">§</a>
|
||
</div>
|
||
<p>Fetch the model from the server, merging the response with the model’s
|
||
local attributes. Any changed attributes will trigger a “change” event.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">fetch</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">options</span>) {
|
||
options = _.<span class="hljs-title function_">extend</span>({<span class="hljs-attr">parse</span>: <span class="hljs-literal">true</span>}, options);
|
||
<span class="hljs-keyword">var</span> model = <span class="hljs-variable language_">this</span>;
|
||
<span class="hljs-keyword">var</span> success = options.<span class="hljs-property">success</span>;
|
||
options.<span class="hljs-property">success</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">resp</span>) {
|
||
<span class="hljs-keyword">var</span> serverAttrs = options.<span class="hljs-property">parse</span> ? model.<span class="hljs-title function_">parse</span>(resp, options) : resp;
|
||
<span class="hljs-keyword">if</span> (!model.<span class="hljs-title function_">set</span>(serverAttrs, options)) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
|
||
<span class="hljs-keyword">if</span> (success) success.<span class="hljs-title function_">call</span>(options.<span class="hljs-property">context</span>, model, resp, options);
|
||
model.<span class="hljs-title function_">trigger</span>(<span class="hljs-string">'sync'</span>, model, resp, options);
|
||
};
|
||
<span class="hljs-title function_">wrapError</span>(<span class="hljs-variable language_">this</span>, options);
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">sync</span>(<span class="hljs-string">'read'</span>, <span class="hljs-variable language_">this</span>, options);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-88">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-88">§</a>
|
||
</div>
|
||
<p>Set a hash of model attributes, and sync the model to the server.
|
||
If the server returns an attributes hash that differs, the model’s
|
||
state will be <code>set</code> again.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">save</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">key, val, options</span>) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-89">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-89">§</a>
|
||
</div>
|
||
<p>Handle both <code>"key", value</code> and <code>{key: value}</code> -style arguments.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> attrs;
|
||
<span class="hljs-keyword">if</span> (key == <span class="hljs-literal">null</span> || <span class="hljs-keyword">typeof</span> key === <span class="hljs-string">'object'</span>) {
|
||
attrs = key;
|
||
options = val;
|
||
} <span class="hljs-keyword">else</span> {
|
||
(attrs = {})[key] = val;
|
||
}
|
||
|
||
options = _.<span class="hljs-title function_">extend</span>({<span class="hljs-attr">validate</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">parse</span>: <span class="hljs-literal">true</span>}, options);
|
||
<span class="hljs-keyword">var</span> wait = options.<span class="hljs-property">wait</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-90">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-90">§</a>
|
||
</div>
|
||
<p>If we’re not waiting and attributes exist, save acts as
|
||
<code>set(attr).save(null, opts)</code> with validation. Otherwise, check if
|
||
the model will be valid when the attributes, if any, are set.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (attrs && !wait) {
|
||
<span class="hljs-keyword">if</span> (!<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">set</span>(attrs, options)) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
|
||
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (!<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_validate</span>(attrs, options)) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-91">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-91">§</a>
|
||
</div>
|
||
<p>After a successful server-side save, the client is (optionally)
|
||
updated with the server-side state.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> model = <span class="hljs-variable language_">this</span>;
|
||
<span class="hljs-keyword">var</span> success = options.<span class="hljs-property">success</span>;
|
||
<span class="hljs-keyword">var</span> attributes = <span class="hljs-variable language_">this</span>.<span class="hljs-property">attributes</span>;
|
||
options.<span class="hljs-property">success</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">resp</span>) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-92">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-92">§</a>
|
||
</div>
|
||
<p>Ensure attributes are restored during synchronous saves.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> model.<span class="hljs-property">attributes</span> = attributes;
|
||
<span class="hljs-keyword">var</span> serverAttrs = options.<span class="hljs-property">parse</span> ? model.<span class="hljs-title function_">parse</span>(resp, options) : resp;
|
||
<span class="hljs-keyword">if</span> (wait) serverAttrs = _.<span class="hljs-title function_">extend</span>({}, attrs, serverAttrs);
|
||
<span class="hljs-keyword">if</span> (serverAttrs && !model.<span class="hljs-title function_">set</span>(serverAttrs, options)) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
|
||
<span class="hljs-keyword">if</span> (success) success.<span class="hljs-title function_">call</span>(options.<span class="hljs-property">context</span>, model, resp, options);
|
||
model.<span class="hljs-title function_">trigger</span>(<span class="hljs-string">'sync'</span>, model, resp, options);
|
||
};
|
||
<span class="hljs-title function_">wrapError</span>(<span class="hljs-variable language_">this</span>, options);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-93">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-93">§</a>
|
||
</div>
|
||
<p>Set temporary attributes if <code>{wait: true}</code> to properly find new ids.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (attrs && wait) <span class="hljs-variable language_">this</span>.<span class="hljs-property">attributes</span> = _.<span class="hljs-title function_">extend</span>({}, attributes, attrs);
|
||
|
||
<span class="hljs-keyword">var</span> method = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">isNew</span>() ? <span class="hljs-string">'create'</span> : options.<span class="hljs-property">patch</span> ? <span class="hljs-string">'patch'</span> : <span class="hljs-string">'update'</span>;
|
||
<span class="hljs-keyword">if</span> (method === <span class="hljs-string">'patch'</span> && !options.<span class="hljs-property">attrs</span>) options.<span class="hljs-property">attrs</span> = attrs;
|
||
<span class="hljs-keyword">var</span> xhr = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">sync</span>(method, <span class="hljs-variable language_">this</span>, options);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-94">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-94">§</a>
|
||
</div>
|
||
<p>Restore attributes.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-variable language_">this</span>.<span class="hljs-property">attributes</span> = attributes;
|
||
|
||
<span class="hljs-keyword">return</span> xhr;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-95">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-95">§</a>
|
||
</div>
|
||
<p>Destroy this model on the server if it was already persisted.
|
||
Optimistically removes the model from its collection, if it has one.
|
||
If <code>wait: true</code> is passed, waits for the server to respond before removal.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">destroy</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">options</span>) {
|
||
options = options ? _.<span class="hljs-title function_">clone</span>(options) : {};
|
||
<span class="hljs-keyword">var</span> model = <span class="hljs-variable language_">this</span>;
|
||
<span class="hljs-keyword">var</span> success = options.<span class="hljs-property">success</span>;
|
||
<span class="hljs-keyword">var</span> wait = options.<span class="hljs-property">wait</span>;
|
||
|
||
<span class="hljs-keyword">var</span> destroy = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
model.<span class="hljs-title function_">stopListening</span>();
|
||
model.<span class="hljs-title function_">trigger</span>(<span class="hljs-string">'destroy'</span>, model, model.<span class="hljs-property">collection</span>, options);
|
||
};
|
||
|
||
options.<span class="hljs-property">success</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">resp</span>) {
|
||
<span class="hljs-keyword">if</span> (wait) <span class="hljs-title function_">destroy</span>();
|
||
<span class="hljs-keyword">if</span> (success) success.<span class="hljs-title function_">call</span>(options.<span class="hljs-property">context</span>, model, resp, options);
|
||
<span class="hljs-keyword">if</span> (!model.<span class="hljs-title function_">isNew</span>()) model.<span class="hljs-title function_">trigger</span>(<span class="hljs-string">'sync'</span>, model, resp, options);
|
||
};
|
||
|
||
<span class="hljs-keyword">var</span> xhr = <span class="hljs-literal">false</span>;
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">isNew</span>()) {
|
||
_.<span class="hljs-title function_">defer</span>(options.<span class="hljs-property">success</span>);
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-title function_">wrapError</span>(<span class="hljs-variable language_">this</span>, options);
|
||
xhr = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">sync</span>(<span class="hljs-string">'delete'</span>, <span class="hljs-variable language_">this</span>, options);
|
||
}
|
||
<span class="hljs-keyword">if</span> (!wait) <span class="hljs-title function_">destroy</span>();
|
||
<span class="hljs-keyword">return</span> xhr;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-96">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-96">§</a>
|
||
</div>
|
||
<p>Default URL for the model’s representation on the server – if you’re
|
||
using Backbone’s restful methods, override this to change the endpoint
|
||
that will be called.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">url</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">var</span> base =
|
||
_.<span class="hljs-title function_">result</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-string">'urlRoot'</span>) ||
|
||
_.<span class="hljs-title function_">result</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">collection</span>, <span class="hljs-string">'url'</span>) ||
|
||
<span class="hljs-title function_">urlError</span>();
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">isNew</span>()) <span class="hljs-keyword">return</span> base;
|
||
<span class="hljs-keyword">var</span> id = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">get</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">idAttribute</span>);
|
||
<span class="hljs-keyword">return</span> base.<span class="hljs-title function_">replace</span>(<span class="hljs-regexp">/[^\/]$/</span>, <span class="hljs-string">'$&/'</span>) + <span class="hljs-built_in">encodeURIComponent</span>(id);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-97">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-97">§</a>
|
||
</div>
|
||
<p><strong>parse</strong> converts a response into the hash of attributes to be <code>set</code> on
|
||
the model. The default implementation is just to pass the response along.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">parse</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">resp, options</span>) {
|
||
<span class="hljs-keyword">return</span> resp;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-98">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-98">§</a>
|
||
</div>
|
||
<p>Create a new model with identical attributes to this one.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">clone</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">constructor</span>(<span class="hljs-params"><span class="hljs-variable language_">this</span>.attributes</span>);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-99">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-99">§</a>
|
||
</div>
|
||
<p>A model is new if it has never been saved to the server, and lacks an id.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">isNew</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">return</span> !<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">has</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">idAttribute</span>);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-100">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-100">§</a>
|
||
</div>
|
||
<p>Check if the model is currently in a valid state.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">isValid</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">options</span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_validate</span>({}, _.<span class="hljs-title function_">extend</span>({}, options, {<span class="hljs-attr">validate</span>: <span class="hljs-literal">true</span>}));
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-101">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-101">§</a>
|
||
</div>
|
||
<p>Run validation against the next complete set of model attributes,
|
||
returning <code>true</code> if all is well. Otherwise, fire an <code>"invalid"</code> event.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">_validate</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">attrs, options</span>) {
|
||
<span class="hljs-keyword">if</span> (!options.<span class="hljs-property">validate</span> || !<span class="hljs-variable language_">this</span>.<span class="hljs-property">validate</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
|
||
attrs = _.<span class="hljs-title function_">extend</span>({}, <span class="hljs-variable language_">this</span>.<span class="hljs-property">attributes</span>, attrs);
|
||
<span class="hljs-keyword">var</span> error = <span class="hljs-variable language_">this</span>.<span class="hljs-property">validationError</span> = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">validate</span>(attrs, options) || <span class="hljs-literal">null</span>;
|
||
<span class="hljs-keyword">if</span> (!error) <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">trigger</span>(<span class="hljs-string">'invalid'</span>, <span class="hljs-variable language_">this</span>, error, _.<span class="hljs-title function_">extend</span>(options, {<span class="hljs-attr">validationError</span>: error}));
|
||
<span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
|
||
}
|
||
|
||
});</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-102">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-102">§</a>
|
||
</div>
|
||
<h2 id="backbonecollection">Backbone.Collection</h2>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-103">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-103">§</a>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-104">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-104">§</a>
|
||
</div>
|
||
<p>If models tend to represent a single row of data, a Backbone Collection is
|
||
more analogous to a table full of data … or a small slice or page of that
|
||
table, or a collection of rows that belong together for a particular reason
|
||
– all of the messages in this particular folder, all of the documents
|
||
belonging to this particular author, and so on. Collections maintain
|
||
indexes of their models, both in order, and for lookup by <code>id</code>.</p>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-105">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-105">§</a>
|
||
</div>
|
||
<p>Create a new <strong>Collection</strong>, perhaps to contain a specific type of <code>model</code>.
|
||
If a <code>comparator</code> is specified, the Collection will maintain
|
||
its models in sort order, as they’re added and removed.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> <span class="hljs-title class_">Collection</span> = <span class="hljs-title class_">Backbone</span>.<span class="hljs-property">Collection</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">models, options</span>) {
|
||
options || (options = {});
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">preinitialize</span>.<span class="hljs-title function_">apply</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-variable language_">arguments</span>);
|
||
<span class="hljs-keyword">if</span> (options.<span class="hljs-property">model</span>) <span class="hljs-variable language_">this</span>.<span class="hljs-property">model</span> = options.<span class="hljs-property">model</span>;
|
||
<span class="hljs-keyword">if</span> (options.<span class="hljs-property">comparator</span> !== <span class="hljs-keyword">void</span> <span class="hljs-number">0</span>) <span class="hljs-variable language_">this</span>.<span class="hljs-property">comparator</span> = options.<span class="hljs-property">comparator</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_reset</span>();
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">initialize</span>.<span class="hljs-title function_">apply</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-variable language_">arguments</span>);
|
||
<span class="hljs-keyword">if</span> (models) <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">reset</span>(models, _.<span class="hljs-title function_">extend</span>({<span class="hljs-attr">silent</span>: <span class="hljs-literal">true</span>}, options));
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-106">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-106">§</a>
|
||
</div>
|
||
<p>Default options for <code>Collection#set</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> setOptions = {<span class="hljs-attr">add</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">remove</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">merge</span>: <span class="hljs-literal">true</span>};
|
||
<span class="hljs-keyword">var</span> addOptions = {<span class="hljs-attr">add</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">remove</span>: <span class="hljs-literal">false</span>};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-107">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-107">§</a>
|
||
</div>
|
||
<p>Splices <code>insert</code> into <code>array</code> at index <code>at</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> splice = <span class="hljs-keyword">function</span>(<span class="hljs-params">array, insert, at</span>) {
|
||
at = <span class="hljs-title class_">Math</span>.<span class="hljs-title function_">min</span>(<span class="hljs-title class_">Math</span>.<span class="hljs-title function_">max</span>(at, <span class="hljs-number">0</span>), array.<span class="hljs-property">length</span>);
|
||
<span class="hljs-keyword">var</span> tail = <span class="hljs-title class_">Array</span>(array.<span class="hljs-property">length</span> - at);
|
||
<span class="hljs-keyword">var</span> length = insert.<span class="hljs-property">length</span>;
|
||
<span class="hljs-keyword">var</span> i;
|
||
<span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i < tail.<span class="hljs-property">length</span>; i++) tail[i] = array[i + at];
|
||
<span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i < length; i++) array[i + at] = insert[i];
|
||
<span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i < tail.<span class="hljs-property">length</span>; i++) array[i + length + at] = tail[i];
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-108">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-108">§</a>
|
||
</div>
|
||
<p>Define the Collection’s inheritable methods.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _.<span class="hljs-title function_">extend</span>(<span class="hljs-title class_">Collection</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>, <span class="hljs-title class_">Events</span>, {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-109">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-109">§</a>
|
||
</div>
|
||
<p>The default model for a collection is just a <strong>Backbone.Model</strong>.
|
||
This should be overridden in most cases.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">model</span>: <span class="hljs-title class_">Model</span>,</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-110">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-110">§</a>
|
||
</div>
|
||
<p>preinitialize is an empty function by default. You can override it with a function
|
||
or object. preinitialize will run before any instantiation logic is run in the Collection.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">preinitialize</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-111">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-111">§</a>
|
||
</div>
|
||
<p>Initialize is an empty function by default. Override it with your own
|
||
initialization logic.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">initialize</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-112">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-112">§</a>
|
||
</div>
|
||
<p>The JSON representation of a Collection is an array of the
|
||
models’ attributes.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">toJSON</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">options</span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">map</span>(<span class="hljs-keyword">function</span>(<span class="hljs-params">model</span>) { <span class="hljs-keyword">return</span> model.<span class="hljs-title function_">toJSON</span>(options); });
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-113">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-113">§</a>
|
||
</div>
|
||
<p>Proxy <code>Backbone.sync</code> by default.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">sync</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-title class_">Backbone</span>.<span class="hljs-property">sync</span>.<span class="hljs-title function_">apply</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-variable language_">arguments</span>);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-114">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-114">§</a>
|
||
</div>
|
||
<p>Add a model, or list of models to the set. <code>models</code> may be Backbone
|
||
Models or raw JavaScript objects to be converted to Models, or any
|
||
combination of the two.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">add</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">models, options</span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">set</span>(models, _.<span class="hljs-title function_">extend</span>({<span class="hljs-attr">merge</span>: <span class="hljs-literal">false</span>}, options, addOptions));
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-115">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-115">§</a>
|
||
</div>
|
||
<p>Remove a model, or a list of models from the set.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">remove</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">models, options</span>) {
|
||
options = _.<span class="hljs-title function_">extend</span>({}, options);
|
||
<span class="hljs-keyword">var</span> singular = !_.<span class="hljs-title function_">isArray</span>(models);
|
||
models = singular ? [models] : models.<span class="hljs-title function_">slice</span>();
|
||
<span class="hljs-keyword">var</span> removed = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_removeModels</span>(models, options);
|
||
<span class="hljs-keyword">if</span> (!options.<span class="hljs-property">silent</span> && removed.<span class="hljs-property">length</span>) {
|
||
options.<span class="hljs-property">changes</span> = {<span class="hljs-attr">added</span>: [], <span class="hljs-attr">merged</span>: [], <span class="hljs-attr">removed</span>: removed};
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">trigger</span>(<span class="hljs-string">'update'</span>, <span class="hljs-variable language_">this</span>, options);
|
||
}
|
||
<span class="hljs-keyword">return</span> singular ? removed[<span class="hljs-number">0</span>] : removed;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-116">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-116">§</a>
|
||
</div>
|
||
<p>Update a collection by <code>set</code>-ing a new list of models, adding new ones,
|
||
removing models that are no longer present, and merging models that
|
||
already exist in the collection, as necessary. Similar to <strong>Model#set</strong>,
|
||
the core operation for updating the data contained by the collection.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">set</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">models, options</span>) {
|
||
<span class="hljs-keyword">if</span> (models == <span class="hljs-literal">null</span>) <span class="hljs-keyword">return</span>;
|
||
|
||
options = _.<span class="hljs-title function_">extend</span>({}, setOptions, options);
|
||
<span class="hljs-keyword">if</span> (options.<span class="hljs-property">parse</span> && !<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_isModel</span>(models)) {
|
||
models = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">parse</span>(models, options) || [];
|
||
}
|
||
|
||
<span class="hljs-keyword">var</span> singular = !_.<span class="hljs-title function_">isArray</span>(models);
|
||
models = singular ? [models] : models.<span class="hljs-title function_">slice</span>();
|
||
|
||
<span class="hljs-keyword">var</span> at = options.<span class="hljs-property">at</span>;
|
||
<span class="hljs-keyword">if</span> (at != <span class="hljs-literal">null</span>) at = +at;
|
||
<span class="hljs-keyword">if</span> (at > <span class="hljs-variable language_">this</span>.<span class="hljs-property">length</span>) at = <span class="hljs-variable language_">this</span>.<span class="hljs-property">length</span>;
|
||
<span class="hljs-keyword">if</span> (at < <span class="hljs-number">0</span>) at += <span class="hljs-variable language_">this</span>.<span class="hljs-property">length</span> + <span class="hljs-number">1</span>;
|
||
|
||
<span class="hljs-keyword">var</span> set = [];
|
||
<span class="hljs-keyword">var</span> toAdd = [];
|
||
<span class="hljs-keyword">var</span> toMerge = [];
|
||
<span class="hljs-keyword">var</span> toRemove = [];
|
||
<span class="hljs-keyword">var</span> modelMap = {};
|
||
|
||
<span class="hljs-keyword">var</span> add = options.<span class="hljs-property">add</span>;
|
||
<span class="hljs-keyword">var</span> merge = options.<span class="hljs-property">merge</span>;
|
||
<span class="hljs-keyword">var</span> remove = options.<span class="hljs-property">remove</span>;
|
||
|
||
<span class="hljs-keyword">var</span> sort = <span class="hljs-literal">false</span>;
|
||
<span class="hljs-keyword">var</span> sortable = <span class="hljs-variable language_">this</span>.<span class="hljs-property">comparator</span> && at == <span class="hljs-literal">null</span> && options.<span class="hljs-property">sort</span> !== <span class="hljs-literal">false</span>;
|
||
<span class="hljs-keyword">var</span> sortAttr = _.<span class="hljs-title function_">isString</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">comparator</span>) ? <span class="hljs-variable language_">this</span>.<span class="hljs-property">comparator</span> : <span class="hljs-literal">null</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-117">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-117">§</a>
|
||
</div>
|
||
<p>Turn bare objects into model references, and prevent invalid models
|
||
from being added.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> model, i;
|
||
<span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i < models.<span class="hljs-property">length</span>; i++) {
|
||
model = models[i];</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-118">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-118">§</a>
|
||
</div>
|
||
<p>If a duplicate is found, prevent it from being added and
|
||
optionally merge it into the existing model.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> existing = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">get</span>(model);
|
||
<span class="hljs-keyword">if</span> (existing) {
|
||
<span class="hljs-keyword">if</span> (merge && model !== existing) {
|
||
<span class="hljs-keyword">var</span> attrs = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_isModel</span>(model) ? model.<span class="hljs-property">attributes</span> : model;
|
||
<span class="hljs-keyword">if</span> (options.<span class="hljs-property">parse</span>) attrs = existing.<span class="hljs-title function_">parse</span>(attrs, options);
|
||
existing.<span class="hljs-title function_">set</span>(attrs, options);
|
||
toMerge.<span class="hljs-title function_">push</span>(existing);
|
||
<span class="hljs-keyword">if</span> (sortable && !sort) sort = existing.<span class="hljs-title function_">hasChanged</span>(sortAttr);
|
||
}
|
||
<span class="hljs-keyword">if</span> (!modelMap[existing.<span class="hljs-property">cid</span>]) {
|
||
modelMap[existing.<span class="hljs-property">cid</span>] = <span class="hljs-literal">true</span>;
|
||
set.<span class="hljs-title function_">push</span>(existing);
|
||
}
|
||
models[i] = existing;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-119">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-119">§</a>
|
||
</div>
|
||
<p>If this is a new, valid model, push it to the <code>toAdd</code> list.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (add) {
|
||
model = models[i] = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_prepareModel</span>(model, options);
|
||
<span class="hljs-keyword">if</span> (model) {
|
||
toAdd.<span class="hljs-title function_">push</span>(model);
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_addReference</span>(model, options);
|
||
modelMap[model.<span class="hljs-property">cid</span>] = <span class="hljs-literal">true</span>;
|
||
set.<span class="hljs-title function_">push</span>(model);
|
||
}
|
||
}
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-120">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-120">§</a>
|
||
</div>
|
||
<p>Remove stale models.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (remove) {
|
||
<span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i < <span class="hljs-variable language_">this</span>.<span class="hljs-property">length</span>; i++) {
|
||
model = <span class="hljs-variable language_">this</span>.<span class="hljs-property">models</span>[i];
|
||
<span class="hljs-keyword">if</span> (!modelMap[model.<span class="hljs-property">cid</span>]) toRemove.<span class="hljs-title function_">push</span>(model);
|
||
}
|
||
<span class="hljs-keyword">if</span> (toRemove.<span class="hljs-property">length</span>) <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_removeModels</span>(toRemove, options);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-121">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-121">§</a>
|
||
</div>
|
||
<p>See if sorting is needed, update <code>length</code> and splice in new models.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> orderChanged = <span class="hljs-literal">false</span>;
|
||
<span class="hljs-keyword">var</span> replace = !sortable && add && remove;
|
||
<span class="hljs-keyword">if</span> (set.<span class="hljs-property">length</span> && replace) {
|
||
orderChanged = <span class="hljs-variable language_">this</span>.<span class="hljs-property">length</span> !== set.<span class="hljs-property">length</span> || _.<span class="hljs-title function_">some</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">models</span>, <span class="hljs-keyword">function</span>(<span class="hljs-params">m, index</span>) {
|
||
<span class="hljs-keyword">return</span> m !== set[index];
|
||
});
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">models</span>.<span class="hljs-property">length</span> = <span class="hljs-number">0</span>;
|
||
<span class="hljs-title function_">splice</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">models</span>, set, <span class="hljs-number">0</span>);
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">length</span> = <span class="hljs-variable language_">this</span>.<span class="hljs-property">models</span>.<span class="hljs-property">length</span>;
|
||
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (toAdd.<span class="hljs-property">length</span>) {
|
||
<span class="hljs-keyword">if</span> (sortable) sort = <span class="hljs-literal">true</span>;
|
||
<span class="hljs-title function_">splice</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">models</span>, toAdd, at == <span class="hljs-literal">null</span> ? <span class="hljs-variable language_">this</span>.<span class="hljs-property">length</span> : at);
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">length</span> = <span class="hljs-variable language_">this</span>.<span class="hljs-property">models</span>.<span class="hljs-property">length</span>;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-122">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-122">§</a>
|
||
</div>
|
||
<p>Silently sort the collection if appropriate.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (sort) <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">sort</span>({<span class="hljs-attr">silent</span>: <span class="hljs-literal">true</span>});</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-123">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-123">§</a>
|
||
</div>
|
||
<p>Unless silenced, it’s time to fire all appropriate add/sort/update events.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!options.<span class="hljs-property">silent</span>) {
|
||
<span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i < toAdd.<span class="hljs-property">length</span>; i++) {
|
||
<span class="hljs-keyword">if</span> (at != <span class="hljs-literal">null</span>) options.<span class="hljs-property">index</span> = at + i;
|
||
model = toAdd[i];
|
||
model.<span class="hljs-title function_">trigger</span>(<span class="hljs-string">'add'</span>, model, <span class="hljs-variable language_">this</span>, options);
|
||
}
|
||
<span class="hljs-keyword">if</span> (sort || orderChanged) <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">trigger</span>(<span class="hljs-string">'sort'</span>, <span class="hljs-variable language_">this</span>, options);
|
||
<span class="hljs-keyword">if</span> (toAdd.<span class="hljs-property">length</span> || toRemove.<span class="hljs-property">length</span> || toMerge.<span class="hljs-property">length</span>) {
|
||
options.<span class="hljs-property">changes</span> = {
|
||
<span class="hljs-attr">added</span>: toAdd,
|
||
<span class="hljs-attr">removed</span>: toRemove,
|
||
<span class="hljs-attr">merged</span>: toMerge
|
||
};
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">trigger</span>(<span class="hljs-string">'update'</span>, <span class="hljs-variable language_">this</span>, options);
|
||
}
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-124">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-124">§</a>
|
||
</div>
|
||
<p>Return the added (or merged) model (or models).</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> singular ? models[<span class="hljs-number">0</span>] : models;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-125">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-125">§</a>
|
||
</div>
|
||
<p>When you have more items than you want to add or remove individually,
|
||
you can reset the entire set with a new list of models, without firing
|
||
any granular <code>add</code> or <code>remove</code> events. Fires <code>reset</code> when finished.
|
||
Useful for bulk operations and optimizations.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">reset</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">models, options</span>) {
|
||
options = options ? _.<span class="hljs-title function_">clone</span>(options) : {};
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < <span class="hljs-variable language_">this</span>.<span class="hljs-property">models</span>.<span class="hljs-property">length</span>; i++) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_removeReference</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">models</span>[i], options);
|
||
}
|
||
options.<span class="hljs-property">previousModels</span> = <span class="hljs-variable language_">this</span>.<span class="hljs-property">models</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_reset</span>();
|
||
models = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">add</span>(models, _.<span class="hljs-title function_">extend</span>({<span class="hljs-attr">silent</span>: <span class="hljs-literal">true</span>}, options));
|
||
<span class="hljs-keyword">if</span> (!options.<span class="hljs-property">silent</span>) <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">trigger</span>(<span class="hljs-string">'reset'</span>, <span class="hljs-variable language_">this</span>, options);
|
||
<span class="hljs-keyword">return</span> models;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-126">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-126">§</a>
|
||
</div>
|
||
<p>Add a model to the end of the collection.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">push</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">model, options</span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">add</span>(model, _.<span class="hljs-title function_">extend</span>({<span class="hljs-attr">at</span>: <span class="hljs-variable language_">this</span>.<span class="hljs-property">length</span>}, options));
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-127">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-127">§</a>
|
||
</div>
|
||
<p>Remove a model from the end of the collection.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">pop</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">options</span>) {
|
||
<span class="hljs-keyword">var</span> model = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">at</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">length</span> - <span class="hljs-number">1</span>);
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">remove</span>(model, options);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-128">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-128">§</a>
|
||
</div>
|
||
<p>Add a model to the beginning of the collection.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">unshift</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">model, options</span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">add</span>(model, _.<span class="hljs-title function_">extend</span>({<span class="hljs-attr">at</span>: <span class="hljs-number">0</span>}, options));
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-129">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-129">§</a>
|
||
</div>
|
||
<p>Remove a model from the beginning of the collection.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">shift</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">options</span>) {
|
||
<span class="hljs-keyword">var</span> model = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">at</span>(<span class="hljs-number">0</span>);
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">remove</span>(model, options);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-130">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-130">§</a>
|
||
</div>
|
||
<p>Slice out a sub-array of models from the collection.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">slice</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">return</span> slice.<span class="hljs-title function_">apply</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">models</span>, <span class="hljs-variable language_">arguments</span>);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-131">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-131">§</a>
|
||
</div>
|
||
<p>Get a model from the set by id, cid, model object with id or cid
|
||
properties, or an attributes object that is transformed through modelId.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">get</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">obj</span>) {
|
||
<span class="hljs-keyword">if</span> (obj == <span class="hljs-literal">null</span>) <span class="hljs-keyword">return</span> <span class="hljs-keyword">void</span> <span class="hljs-number">0</span>;
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">_byId</span>[obj] ||
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_byId</span>[<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">modelId</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_isModel</span>(obj) ? obj.<span class="hljs-property">attributes</span> : obj, obj.<span class="hljs-property">idAttribute</span>)] ||
|
||
obj.<span class="hljs-property">cid</span> && <span class="hljs-variable language_">this</span>.<span class="hljs-property">_byId</span>[obj.<span class="hljs-property">cid</span>];
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-132">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-132">§</a>
|
||
</div>
|
||
<p>Returns <code>true</code> if the model is in the collection.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">has</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">obj</span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">get</span>(obj) != <span class="hljs-literal">null</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-133">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-133">§</a>
|
||
</div>
|
||
<p>Get the model at the given index.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">at</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">index</span>) {
|
||
<span class="hljs-keyword">if</span> (index < <span class="hljs-number">0</span>) index += <span class="hljs-variable language_">this</span>.<span class="hljs-property">length</span>;
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">models</span>[index];
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-134">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-134">§</a>
|
||
</div>
|
||
<p>Return models with matching attributes. Useful for simple cases of
|
||
<code>filter</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">where</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">attrs, first</span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>[first ? <span class="hljs-string">'find'</span> : <span class="hljs-string">'filter'</span>](attrs);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-135">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-135">§</a>
|
||
</div>
|
||
<p>Return the first model with matching attributes. Useful for simple cases
|
||
of <code>find</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">findWhere</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">attrs</span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">where</span>(attrs, <span class="hljs-literal">true</span>);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-136">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-136">§</a>
|
||
</div>
|
||
<p>Force the collection to re-sort itself. You don’t need to call this under
|
||
normal circumstances, as the set will maintain sort order as each item
|
||
is added.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">sort</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">options</span>) {
|
||
<span class="hljs-keyword">var</span> comparator = <span class="hljs-variable language_">this</span>.<span class="hljs-property">comparator</span>;
|
||
<span class="hljs-keyword">if</span> (!comparator) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Error</span>(<span class="hljs-string">'Cannot sort a set without a comparator'</span>);
|
||
options || (options = {});
|
||
|
||
<span class="hljs-keyword">var</span> length = comparator.<span class="hljs-property">length</span>;
|
||
<span class="hljs-keyword">if</span> (_.<span class="hljs-title function_">isFunction</span>(comparator)) comparator = comparator.<span class="hljs-title function_">bind</span>(<span class="hljs-variable language_">this</span>);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-137">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-137">§</a>
|
||
</div>
|
||
<p>Run sort based on type of <code>comparator</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (length === <span class="hljs-number">1</span> || _.<span class="hljs-title function_">isString</span>(comparator)) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">models</span> = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">sortBy</span>(comparator);
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">models</span>.<span class="hljs-title function_">sort</span>(comparator);
|
||
}
|
||
<span class="hljs-keyword">if</span> (!options.<span class="hljs-property">silent</span>) <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">trigger</span>(<span class="hljs-string">'sort'</span>, <span class="hljs-variable language_">this</span>, options);
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-138">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-138">§</a>
|
||
</div>
|
||
<p>Pluck an attribute from each model in the collection.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">pluck</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">attr</span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">map</span>(attr + <span class="hljs-string">''</span>);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-139">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-139">§</a>
|
||
</div>
|
||
<p>Fetch the default set of models for this collection, resetting the
|
||
collection when they arrive. If <code>reset: true</code> is passed, the response
|
||
data will be passed through the <code>reset</code> method instead of <code>set</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">fetch</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">options</span>) {
|
||
options = _.<span class="hljs-title function_">extend</span>({<span class="hljs-attr">parse</span>: <span class="hljs-literal">true</span>}, options);
|
||
<span class="hljs-keyword">var</span> success = options.<span class="hljs-property">success</span>;
|
||
<span class="hljs-keyword">var</span> collection = <span class="hljs-variable language_">this</span>;
|
||
options.<span class="hljs-property">success</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">resp</span>) {
|
||
<span class="hljs-keyword">var</span> method = options.<span class="hljs-property">reset</span> ? <span class="hljs-string">'reset'</span> : <span class="hljs-string">'set'</span>;
|
||
collection[method](resp, options);
|
||
<span class="hljs-keyword">if</span> (success) success.<span class="hljs-title function_">call</span>(options.<span class="hljs-property">context</span>, collection, resp, options);
|
||
collection.<span class="hljs-title function_">trigger</span>(<span class="hljs-string">'sync'</span>, collection, resp, options);
|
||
};
|
||
<span class="hljs-title function_">wrapError</span>(<span class="hljs-variable language_">this</span>, options);
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">sync</span>(<span class="hljs-string">'read'</span>, <span class="hljs-variable language_">this</span>, options);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-140">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-140">§</a>
|
||
</div>
|
||
<p>Create a new instance of a model in this collection. Add the model to the
|
||
collection immediately, unless <code>wait: true</code> is passed, in which case we
|
||
wait for the server to agree.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">create</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">model, options</span>) {
|
||
options = options ? _.<span class="hljs-title function_">clone</span>(options) : {};
|
||
<span class="hljs-keyword">var</span> wait = options.<span class="hljs-property">wait</span>;
|
||
model = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_prepareModel</span>(model, options);
|
||
<span class="hljs-keyword">if</span> (!model) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
|
||
<span class="hljs-keyword">if</span> (!wait) <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">add</span>(model, options);
|
||
<span class="hljs-keyword">var</span> collection = <span class="hljs-variable language_">this</span>;
|
||
<span class="hljs-keyword">var</span> success = options.<span class="hljs-property">success</span>;
|
||
options.<span class="hljs-property">success</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">m, resp, callbackOpts</span>) {
|
||
<span class="hljs-keyword">if</span> (wait) {
|
||
m.<span class="hljs-title function_">off</span>(<span class="hljs-string">'error'</span>, collection.<span class="hljs-property">_forwardPristineError</span>, collection);
|
||
collection.<span class="hljs-title function_">add</span>(m, callbackOpts);
|
||
}
|
||
<span class="hljs-keyword">if</span> (success) success.<span class="hljs-title function_">call</span>(callbackOpts.<span class="hljs-property">context</span>, m, resp, callbackOpts);
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-141">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-141">§</a>
|
||
</div>
|
||
<p>In case of wait:true, our collection is not listening to any
|
||
of the model’s events yet, so it will not forward the error
|
||
event. In this special case, we need to listen for it
|
||
separately and handle the event just once.
|
||
(The reason we don’t need to do this for the sync event is
|
||
in the success handler above: we add the model first, which
|
||
causes the collection to listen, and then invoke the callback
|
||
that triggers the event.)</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (wait) {
|
||
model.<span class="hljs-title function_">once</span>(<span class="hljs-string">'error'</span>, <span class="hljs-variable language_">this</span>.<span class="hljs-property">_forwardPristineError</span>, <span class="hljs-variable language_">this</span>);
|
||
}
|
||
model.<span class="hljs-title function_">save</span>(<span class="hljs-literal">null</span>, options);
|
||
<span class="hljs-keyword">return</span> model;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-142">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-142">§</a>
|
||
</div>
|
||
<p><strong>parse</strong> converts a response into a list of models to be added to the
|
||
collection. The default implementation is just to pass it through.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">parse</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">resp, options</span>) {
|
||
<span class="hljs-keyword">return</span> resp;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-143">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-143">§</a>
|
||
</div>
|
||
<p>Create a new collection with an identical list of models as this one.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">clone</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">constructor</span>(<span class="hljs-params"><span class="hljs-variable language_">this</span>.models, {
|
||
model: <span class="hljs-variable language_">this</span>.model,
|
||
comparator: <span class="hljs-variable language_">this</span>.comparator
|
||
}</span>);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-144">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-144">§</a>
|
||
</div>
|
||
<p>Define how to uniquely identify models in the collection.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">modelId</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">attrs, idAttribute</span>) {
|
||
<span class="hljs-keyword">return</span> attrs[idAttribute || <span class="hljs-variable language_">this</span>.<span class="hljs-property">model</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">idAttribute</span> || <span class="hljs-string">'id'</span>];
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-145">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-145">§</a>
|
||
</div>
|
||
<p>Get an iterator of all models in this collection.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">values</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">CollectionIterator</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-variable constant_">ITERATOR_VALUES</span>);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-146">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-146">§</a>
|
||
</div>
|
||
<p>Get an iterator of all model IDs in this collection.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">keys</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">CollectionIterator</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-variable constant_">ITERATOR_KEYS</span>);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-147">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-147">§</a>
|
||
</div>
|
||
<p>Get an iterator of all [ID, model] tuples in this collection.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">entries</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">CollectionIterator</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-variable constant_">ITERATOR_KEYSVALUES</span>);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-148">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-148">§</a>
|
||
</div>
|
||
<p>Private method to reset all internal state. Called when the collection
|
||
is first initialized or reset.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">_reset</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">length</span> = <span class="hljs-number">0</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">models</span> = [];
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_byId</span> = {};
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-149">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-149">§</a>
|
||
</div>
|
||
<p>Prepare a hash of attributes (or other model) to be added to this
|
||
collection.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">_prepareModel</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">attrs, options</span>) {
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_isModel</span>(attrs)) {
|
||
<span class="hljs-keyword">if</span> (!attrs.<span class="hljs-property">collection</span>) attrs.<span class="hljs-property">collection</span> = <span class="hljs-variable language_">this</span>;
|
||
<span class="hljs-keyword">return</span> attrs;
|
||
}
|
||
options = options ? _.<span class="hljs-title function_">clone</span>(options) : {};
|
||
options.<span class="hljs-property">collection</span> = <span class="hljs-variable language_">this</span>;
|
||
|
||
<span class="hljs-keyword">var</span> model;
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">model</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>) {
|
||
model = <span class="hljs-keyword">new</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">model</span>(attrs, options);
|
||
} <span class="hljs-keyword">else</span> {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-150">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-150">§</a>
|
||
</div>
|
||
<p>ES class methods didn’t have prototype</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> model = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">model</span>(attrs, options);
|
||
}
|
||
|
||
<span class="hljs-keyword">if</span> (!model.<span class="hljs-property">validationError</span>) <span class="hljs-keyword">return</span> model;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">trigger</span>(<span class="hljs-string">'invalid'</span>, <span class="hljs-variable language_">this</span>, model.<span class="hljs-property">validationError</span>, options);
|
||
<span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-151">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-151">§</a>
|
||
</div>
|
||
<p>Internal method called by both remove and set.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">_removeModels</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">models, options</span>) {
|
||
<span class="hljs-keyword">var</span> removed = [];
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < models.<span class="hljs-property">length</span>; i++) {
|
||
<span class="hljs-keyword">var</span> model = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">get</span>(models[i]);
|
||
<span class="hljs-keyword">if</span> (!model) <span class="hljs-keyword">continue</span>;
|
||
|
||
<span class="hljs-keyword">var</span> index = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">indexOf</span>(model);
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">models</span>.<span class="hljs-title function_">splice</span>(index, <span class="hljs-number">1</span>);
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">length</span>--;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-152">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-152">§</a>
|
||
</div>
|
||
<p>Remove references before triggering ‘remove’ event to prevent an
|
||
infinite loop. #3693</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">delete</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">_byId</span>[model.<span class="hljs-property">cid</span>];
|
||
<span class="hljs-keyword">var</span> id = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">modelId</span>(model.<span class="hljs-property">attributes</span>, model.<span class="hljs-property">idAttribute</span>);
|
||
<span class="hljs-keyword">if</span> (id != <span class="hljs-literal">null</span>) <span class="hljs-keyword">delete</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">_byId</span>[id];
|
||
|
||
<span class="hljs-keyword">if</span> (!options.<span class="hljs-property">silent</span>) {
|
||
options.<span class="hljs-property">index</span> = index;
|
||
model.<span class="hljs-title function_">trigger</span>(<span class="hljs-string">'remove'</span>, model, <span class="hljs-variable language_">this</span>, options);
|
||
}
|
||
|
||
removed.<span class="hljs-title function_">push</span>(model);
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_removeReference</span>(model, options);
|
||
}
|
||
<span class="hljs-keyword">if</span> (models.<span class="hljs-property">length</span> > <span class="hljs-number">0</span> && !options.<span class="hljs-property">silent</span>) <span class="hljs-keyword">delete</span> options.<span class="hljs-property">index</span>;
|
||
<span class="hljs-keyword">return</span> removed;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-153">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-153">§</a>
|
||
</div>
|
||
<p>Method for checking whether an object should be considered a model for
|
||
the purposes of adding to the collection.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">_isModel</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">model</span>) {
|
||
<span class="hljs-keyword">return</span> model <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Model</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-154">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-154">§</a>
|
||
</div>
|
||
<p>Internal method to create a model’s ties to a collection.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">_addReference</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">model, options</span>) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_byId</span>[model.<span class="hljs-property">cid</span>] = model;
|
||
<span class="hljs-keyword">var</span> id = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">modelId</span>(model.<span class="hljs-property">attributes</span>, model.<span class="hljs-property">idAttribute</span>);
|
||
<span class="hljs-keyword">if</span> (id != <span class="hljs-literal">null</span>) <span class="hljs-variable language_">this</span>.<span class="hljs-property">_byId</span>[id] = model;
|
||
model.<span class="hljs-title function_">on</span>(<span class="hljs-string">'all'</span>, <span class="hljs-variable language_">this</span>.<span class="hljs-property">_onModelEvent</span>, <span class="hljs-variable language_">this</span>);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-155">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-155">§</a>
|
||
</div>
|
||
<p>Internal method to sever a model’s ties to a collection.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">_removeReference</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">model, options</span>) {
|
||
<span class="hljs-keyword">delete</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">_byId</span>[model.<span class="hljs-property">cid</span>];
|
||
<span class="hljs-keyword">var</span> id = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">modelId</span>(model.<span class="hljs-property">attributes</span>, model.<span class="hljs-property">idAttribute</span>);
|
||
<span class="hljs-keyword">if</span> (id != <span class="hljs-literal">null</span>) <span class="hljs-keyword">delete</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">_byId</span>[id];
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span> === model.<span class="hljs-property">collection</span>) <span class="hljs-keyword">delete</span> model.<span class="hljs-property">collection</span>;
|
||
model.<span class="hljs-title function_">off</span>(<span class="hljs-string">'all'</span>, <span class="hljs-variable language_">this</span>.<span class="hljs-property">_onModelEvent</span>, <span class="hljs-variable language_">this</span>);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-156">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-156">§</a>
|
||
</div>
|
||
<p>Internal method called every time a model in the set fires an event.
|
||
Sets need to update their indexes when models change ids. All other
|
||
events simply proxy through. “add” and “remove” events that originate
|
||
in other collections are ignored.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">_onModelEvent</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">event, model, collection, options</span>) {
|
||
<span class="hljs-keyword">if</span> (model) {
|
||
<span class="hljs-keyword">if</span> ((event === <span class="hljs-string">'add'</span> || event === <span class="hljs-string">'remove'</span>) && collection !== <span class="hljs-variable language_">this</span>) <span class="hljs-keyword">return</span>;
|
||
<span class="hljs-keyword">if</span> (event === <span class="hljs-string">'destroy'</span>) <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">remove</span>(model, options);
|
||
<span class="hljs-keyword">if</span> (event === <span class="hljs-string">'changeId'</span>) {
|
||
<span class="hljs-keyword">var</span> prevId = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">modelId</span>(model.<span class="hljs-title function_">previousAttributes</span>(), model.<span class="hljs-property">idAttribute</span>);
|
||
<span class="hljs-keyword">var</span> id = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">modelId</span>(model.<span class="hljs-property">attributes</span>, model.<span class="hljs-property">idAttribute</span>);
|
||
<span class="hljs-keyword">if</span> (prevId != <span class="hljs-literal">null</span>) <span class="hljs-keyword">delete</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">_byId</span>[prevId];
|
||
<span class="hljs-keyword">if</span> (id != <span class="hljs-literal">null</span>) <span class="hljs-variable language_">this</span>.<span class="hljs-property">_byId</span>[id] = model;
|
||
}
|
||
}
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">trigger</span>.<span class="hljs-title function_">apply</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-variable language_">arguments</span>);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-157">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-157">§</a>
|
||
</div>
|
||
<p>Internal callback method used in <code>create</code>. It serves as a
|
||
stand-in for the <code>_onModelEvent</code> method, which is not yet bound
|
||
during the <code>wait</code> period of the <code>create</code> call. We still want to
|
||
forward any <code>'error'</code> event at the end of the <code>wait</code> period,
|
||
hence a customized callback.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">_forwardPristineError</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">model, collection, options</span>) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-158">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-158">§</a>
|
||
</div>
|
||
<p>Prevent double forward if the model was already in the
|
||
collection before the call to <code>create</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">has</span>(model)) <span class="hljs-keyword">return</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_onModelEvent</span>(<span class="hljs-string">'error'</span>, model, collection, options);
|
||
}
|
||
});</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-159">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-159">§</a>
|
||
</div>
|
||
<p>Defining an @@iterator method implements JavaScript’s Iterable protocol.
|
||
In modern ES2015 browsers, this value is found at Symbol.iterator.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-comment">/* global Symbol */</span>
|
||
<span class="hljs-keyword">var</span> $$iterator = <span class="hljs-keyword">typeof</span> <span class="hljs-title class_">Symbol</span> === <span class="hljs-string">'function'</span> && <span class="hljs-title class_">Symbol</span>.<span class="hljs-property">iterator</span>;
|
||
<span class="hljs-keyword">if</span> ($$iterator) {
|
||
<span class="hljs-title class_">Collection</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>[$$iterator] = <span class="hljs-title class_">Collection</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">values</span>;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-160">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-160">§</a>
|
||
</div>
|
||
<h2 id="collectioniterator">CollectionIterator</h2>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-161">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-161">§</a>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-162">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-162">§</a>
|
||
</div>
|
||
<p>A CollectionIterator implements JavaScript’s Iterator protocol, allowing the
|
||
use of <code>for of</code> loops in modern browsers and interoperation between
|
||
Backbone.Collection and other JavaScript functions and third-party libraries
|
||
which can operate on Iterables.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> <span class="hljs-title class_">CollectionIterator</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">collection, kind</span>) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_collection</span> = collection;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_kind</span> = kind;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_index</span> = <span class="hljs-number">0</span>;
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-163">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-163">§</a>
|
||
</div>
|
||
<p>This “enum” defines the three possible kinds of values which can be emitted
|
||
by a CollectionIterator that correspond to the values(), keys() and entries()
|
||
methods on Collection, respectively.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> <span class="hljs-variable constant_">ITERATOR_VALUES</span> = <span class="hljs-number">1</span>;
|
||
<span class="hljs-keyword">var</span> <span class="hljs-variable constant_">ITERATOR_KEYS</span> = <span class="hljs-number">2</span>;
|
||
<span class="hljs-keyword">var</span> <span class="hljs-variable constant_">ITERATOR_KEYSVALUES</span> = <span class="hljs-number">3</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-164">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-164">§</a>
|
||
</div>
|
||
<p>All Iterators should themselves be Iterable.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> ($$iterator) {
|
||
<span class="hljs-title class_">CollectionIterator</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>[$$iterator] = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
};
|
||
}
|
||
|
||
<span class="hljs-title class_">CollectionIterator</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">next</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">_collection</span>) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-165">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-165">§</a>
|
||
</div>
|
||
<p>Only continue iterating if the iterated collection is long enough.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">_index</span> < <span class="hljs-variable language_">this</span>.<span class="hljs-property">_collection</span>.<span class="hljs-property">length</span>) {
|
||
<span class="hljs-keyword">var</span> model = <span class="hljs-variable language_">this</span>.<span class="hljs-property">_collection</span>.<span class="hljs-title function_">at</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">_index</span>);
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_index</span>++;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-166">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-166">§</a>
|
||
</div>
|
||
<p>Construct a value depending on what kind of values should be iterated.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> value;
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">_kind</span> === <span class="hljs-variable constant_">ITERATOR_VALUES</span>) {
|
||
value = model;
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-keyword">var</span> id = <span class="hljs-variable language_">this</span>.<span class="hljs-property">_collection</span>.<span class="hljs-title function_">modelId</span>(model.<span class="hljs-property">attributes</span>, model.<span class="hljs-property">idAttribute</span>);
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">_kind</span> === <span class="hljs-variable constant_">ITERATOR_KEYS</span>) {
|
||
value = id;
|
||
} <span class="hljs-keyword">else</span> { <span class="hljs-comment">// ITERATOR_KEYSVALUES</span>
|
||
value = [id, model];
|
||
}
|
||
}
|
||
<span class="hljs-keyword">return</span> {<span class="hljs-attr">value</span>: value, <span class="hljs-attr">done</span>: <span class="hljs-literal">false</span>};
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-167">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-167">§</a>
|
||
</div>
|
||
<p>Once exhausted, remove the reference to the collection so future
|
||
calls to the next method always return done.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-variable language_">this</span>.<span class="hljs-property">_collection</span> = <span class="hljs-keyword">void</span> <span class="hljs-number">0</span>;
|
||
}
|
||
|
||
<span class="hljs-keyword">return</span> {<span class="hljs-attr">value</span>: <span class="hljs-keyword">void</span> <span class="hljs-number">0</span>, <span class="hljs-attr">done</span>: <span class="hljs-literal">true</span>};
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-168">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-168">§</a>
|
||
</div>
|
||
<h2 id="backboneview">Backbone.View</h2>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-169">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-169">§</a>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-170">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-170">§</a>
|
||
</div>
|
||
<p>Backbone Views are almost more convention than they are actual code. A View
|
||
is simply a JavaScript object that represents a logical chunk of UI in the
|
||
DOM. This might be a single item, an entire list, a sidebar or panel, or
|
||
even the surrounding frame which wraps your whole app. Defining a chunk of
|
||
UI as a <strong>View</strong> allows you to define your DOM events declaratively, without
|
||
having to worry about render order … and makes it easy for the view to
|
||
react to specific changes in the state of your models.</p>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-171">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-171">§</a>
|
||
</div>
|
||
<p>Creating a Backbone.View creates its initial element outside of the DOM,
|
||
if an existing element is not provided…</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> <span class="hljs-title class_">View</span> = <span class="hljs-title class_">Backbone</span>.<span class="hljs-property">View</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">options</span>) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">cid</span> = _.<span class="hljs-title function_">uniqueId</span>(<span class="hljs-string">'view'</span>);
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">preinitialize</span>.<span class="hljs-title function_">apply</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-variable language_">arguments</span>);
|
||
_.<span class="hljs-title function_">extend</span>(<span class="hljs-variable language_">this</span>, _.<span class="hljs-title function_">pick</span>(options, viewOptions));
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_ensureElement</span>();
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">initialize</span>.<span class="hljs-title function_">apply</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-variable language_">arguments</span>);
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-172">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-172">§</a>
|
||
</div>
|
||
<p>Cached regex to split keys for <code>delegate</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> delegateEventSplitter = <span class="hljs-regexp">/^(\S+)\s*(.*)$/</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-173">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-173">§</a>
|
||
</div>
|
||
<p>List of view options to be set as properties.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> viewOptions = [<span class="hljs-string">'model'</span>, <span class="hljs-string">'collection'</span>, <span class="hljs-string">'el'</span>, <span class="hljs-string">'id'</span>, <span class="hljs-string">'attributes'</span>, <span class="hljs-string">'className'</span>, <span class="hljs-string">'tagName'</span>, <span class="hljs-string">'events'</span>];</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-174">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-174">§</a>
|
||
</div>
|
||
<p>Set up all inheritable <strong>Backbone.View</strong> properties and methods.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _.<span class="hljs-title function_">extend</span>(<span class="hljs-title class_">View</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>, <span class="hljs-title class_">Events</span>, {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-175">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-175">§</a>
|
||
</div>
|
||
<p>The default <code>tagName</code> of a View’s element is <code>"div"</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">tagName</span>: <span class="hljs-string">'div'</span>,</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-176">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-176">§</a>
|
||
</div>
|
||
<p>jQuery delegate for element lookup, scoped to DOM elements within the
|
||
current view. This should be preferred to global lookups where possible.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">$</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">selector</span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">$el</span>.<span class="hljs-title function_">find</span>(selector);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-177">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-177">§</a>
|
||
</div>
|
||
<p>preinitialize is an empty function by default. You can override it with a function
|
||
or object. preinitialize will run before any instantiation logic is run in the View</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">preinitialize</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-178">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-178">§</a>
|
||
</div>
|
||
<p>Initialize is an empty function by default. Override it with your own
|
||
initialization logic.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">initialize</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-179">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-179">§</a>
|
||
</div>
|
||
<p><strong>render</strong> is the core function that your view should override, in order
|
||
to populate its element (<code>this.el</code>), with the appropriate HTML. The
|
||
convention is for <strong>render</strong> to always return <code>this</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">render</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-180">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-180">§</a>
|
||
</div>
|
||
<p>Remove this view by taking the element out of the DOM, and removing any
|
||
applicable Backbone.Events listeners.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">remove</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_removeElement</span>();
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">stopListening</span>();
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-181">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-181">§</a>
|
||
</div>
|
||
<p>Remove this view’s element from the document and all event listeners
|
||
attached to it. Exposed for subclasses using an alternative DOM
|
||
manipulation API.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">_removeElement</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">$el</span>.<span class="hljs-title function_">remove</span>();
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-182">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-182">§</a>
|
||
</div>
|
||
<p>Change the view’s element (<code>this.el</code> property) and re-delegate the
|
||
view’s events on the new element.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">setElement</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">element</span>) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">undelegateEvents</span>();
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_setElement</span>(element);
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">delegateEvents</span>();
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-183">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-183">§</a>
|
||
</div>
|
||
<p>Creates the <code>this.el</code> and <code>this.$el</code> references for this view using the
|
||
given <code>el</code>. <code>el</code> can be a CSS selector or an HTML string, a jQuery
|
||
context or an element. Subclasses can override this to utilize an
|
||
alternative DOM manipulation API and are only required to set the
|
||
<code>this.el</code> property.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">_setElement</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">el</span>) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">$el</span> = el <span class="hljs-keyword">instanceof</span> <span class="hljs-title class_">Backbone</span>.<span class="hljs-property">$</span> ? el : <span class="hljs-title class_">Backbone</span>.$(el);
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">el</span> = <span class="hljs-variable language_">this</span>.<span class="hljs-property">$el</span>[<span class="hljs-number">0</span>];
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-184">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-184">§</a>
|
||
</div>
|
||
<p>Set callbacks, where <code>this.events</code> is a hash of</p>
|
||
<p><em>{“event selector”: “callback”}</em></p>
|
||
<pre><code>{
|
||
<span class="hljs-string">'mousedown .title'</span>: <span class="hljs-string">'edit'</span>,
|
||
<span class="hljs-string">'click .button'</span>: <span class="hljs-string">'save'</span>,
|
||
<span class="hljs-string">'click .open'</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) { ... }
|
||
}
|
||
</code></pre>
|
||
<p>pairs. Callbacks will be bound to the view, with <code>this</code> set properly.
|
||
Uses event delegation for efficiency.
|
||
Omitting the selector binds the event to <code>this.el</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">delegateEvents</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">events</span>) {
|
||
events || (events = _.<span class="hljs-title function_">result</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-string">'events'</span>));
|
||
<span class="hljs-keyword">if</span> (!events) <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">undelegateEvents</span>();
|
||
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> key <span class="hljs-keyword">in</span> events) {
|
||
<span class="hljs-keyword">var</span> method = events[key];
|
||
<span class="hljs-keyword">if</span> (!_.<span class="hljs-title function_">isFunction</span>(method)) method = <span class="hljs-variable language_">this</span>[method];
|
||
<span class="hljs-keyword">if</span> (!method) <span class="hljs-keyword">continue</span>;
|
||
<span class="hljs-keyword">var</span> match = key.<span class="hljs-title function_">match</span>(delegateEventSplitter);
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">delegate</span>(match[<span class="hljs-number">1</span>], match[<span class="hljs-number">2</span>], method.<span class="hljs-title function_">bind</span>(<span class="hljs-variable language_">this</span>));
|
||
}
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-185">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-185">§</a>
|
||
</div>
|
||
<p>Add a single event listener to the view’s element (or a child element
|
||
using <code>selector</code>). This only works for delegate-able events: not <code>focus</code>,
|
||
<code>blur</code>, and not <code>change</code>, <code>submit</code>, and <code>reset</code> in Internet Explorer.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">delegate</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">eventName, selector, listener</span>) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">$el</span>.<span class="hljs-title function_">on</span>(eventName + <span class="hljs-string">'.delegateEvents'</span> + <span class="hljs-variable language_">this</span>.<span class="hljs-property">cid</span>, selector, listener);
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-186">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-186">§</a>
|
||
</div>
|
||
<p>Clears all callbacks previously bound to the view by <code>delegateEvents</code>.
|
||
You usually don’t need to use this, but may wish to if you have multiple
|
||
Backbone views attached to the same DOM element.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">undelegateEvents</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">$el</span>) <span class="hljs-variable language_">this</span>.<span class="hljs-property">$el</span>.<span class="hljs-title function_">off</span>(<span class="hljs-string">'.delegateEvents'</span> + <span class="hljs-variable language_">this</span>.<span class="hljs-property">cid</span>);
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-187">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-187">§</a>
|
||
</div>
|
||
<p>A finer-grained <code>undelegateEvents</code> for removing a single delegated event.
|
||
<code>selector</code> and <code>listener</code> are both optional.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">undelegate</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">eventName, selector, listener</span>) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">$el</span>.<span class="hljs-title function_">off</span>(eventName + <span class="hljs-string">'.delegateEvents'</span> + <span class="hljs-variable language_">this</span>.<span class="hljs-property">cid</span>, selector, listener);
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-188">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-188">§</a>
|
||
</div>
|
||
<p>Produces a DOM element to be assigned to your view. Exposed for
|
||
subclasses using an alternative DOM manipulation API.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">_createElement</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">tagName</span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">createElement</span>(tagName);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-189">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-189">§</a>
|
||
</div>
|
||
<p>Ensure that the View has a DOM element to render into.
|
||
If <code>this.el</code> is a string, pass it through <code>$()</code>, take the first
|
||
matching element, and re-assign it to <code>el</code>. Otherwise, create
|
||
an element from the <code>id</code>, <code>className</code> and <code>tagName</code> properties.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">_ensureElement</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">if</span> (!<span class="hljs-variable language_">this</span>.<span class="hljs-property">el</span>) {
|
||
<span class="hljs-keyword">var</span> attrs = _.<span class="hljs-title function_">extend</span>({}, _.<span class="hljs-title function_">result</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-string">'attributes'</span>));
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">id</span>) attrs.<span class="hljs-property">id</span> = _.<span class="hljs-title function_">result</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-string">'id'</span>);
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">className</span>) attrs[<span class="hljs-string">'class'</span>] = _.<span class="hljs-title function_">result</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-string">'className'</span>);
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">setElement</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_createElement</span>(_.<span class="hljs-title function_">result</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-string">'tagName'</span>)));
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_setAttributes</span>(attrs);
|
||
} <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">setElement</span>(_.<span class="hljs-title function_">result</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-string">'el'</span>));
|
||
}
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-190">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-190">§</a>
|
||
</div>
|
||
<p>Set attributes from a hash on this view’s element. Exposed for
|
||
subclasses using an alternative DOM manipulation API.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">_setAttributes</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">attributes</span>) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">$el</span>.<span class="hljs-title function_">attr</span>(attributes);
|
||
}
|
||
|
||
});</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-191">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-191">§</a>
|
||
</div>
|
||
<p>Proxy Backbone class methods to Underscore functions, wrapping the model’s
|
||
<code>attributes</code> object or collection’s <code>models</code> array behind the scenes.</p>
|
||
<p>collection.filter(function(model) { return model.get(‘age’) > 10 });
|
||
collection.each(this.addView);</p>
|
||
<p><code>Function#apply</code> can be slow so we use the method’s arg count, if we know it.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> addMethod = <span class="hljs-keyword">function</span>(<span class="hljs-params">base, length, method, attribute</span>) {
|
||
<span class="hljs-keyword">switch</span> (length) {
|
||
<span class="hljs-keyword">case</span> <span class="hljs-number">1</span>: <span class="hljs-keyword">return</span> <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">return</span> base[method](<span class="hljs-variable language_">this</span>[attribute]);
|
||
};
|
||
<span class="hljs-keyword">case</span> <span class="hljs-number">2</span>: <span class="hljs-keyword">return</span> <span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) {
|
||
<span class="hljs-keyword">return</span> base[method](<span class="hljs-variable language_">this</span>[attribute], value);
|
||
};
|
||
<span class="hljs-keyword">case</span> <span class="hljs-number">3</span>: <span class="hljs-keyword">return</span> <span class="hljs-keyword">function</span>(<span class="hljs-params">iteratee, context</span>) {
|
||
<span class="hljs-keyword">return</span> base[method](<span class="hljs-variable language_">this</span>[attribute], <span class="hljs-title function_">cb</span>(iteratee, <span class="hljs-variable language_">this</span>), context);
|
||
};
|
||
<span class="hljs-keyword">case</span> <span class="hljs-number">4</span>: <span class="hljs-keyword">return</span> <span class="hljs-keyword">function</span>(<span class="hljs-params">iteratee, defaultVal, context</span>) {
|
||
<span class="hljs-keyword">return</span> base[method](<span class="hljs-variable language_">this</span>[attribute], <span class="hljs-title function_">cb</span>(iteratee, <span class="hljs-variable language_">this</span>), defaultVal, context);
|
||
};
|
||
<span class="hljs-attr">default</span>: <span class="hljs-keyword">return</span> <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">var</span> args = slice.<span class="hljs-title function_">call</span>(<span class="hljs-variable language_">arguments</span>);
|
||
args.<span class="hljs-title function_">unshift</span>(<span class="hljs-variable language_">this</span>[attribute]);
|
||
<span class="hljs-keyword">return</span> base[method].<span class="hljs-title function_">apply</span>(base, args);
|
||
};
|
||
}
|
||
};
|
||
|
||
<span class="hljs-keyword">var</span> addUnderscoreMethods = <span class="hljs-keyword">function</span>(<span class="hljs-params">Class, base, methods, attribute</span>) {
|
||
_.<span class="hljs-title function_">each</span>(methods, <span class="hljs-keyword">function</span>(<span class="hljs-params">length, method</span>) {
|
||
<span class="hljs-keyword">if</span> (base[method]) <span class="hljs-title class_">Class</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>[method] = <span class="hljs-title function_">addMethod</span>(base, length, method, attribute);
|
||
});
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-192">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-192">§</a>
|
||
</div>
|
||
<p>Support <code>collection.sortBy('attr')</code> and <code>collection.findWhere({id: 1})</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> cb = <span class="hljs-keyword">function</span>(<span class="hljs-params">iteratee, instance</span>) {
|
||
<span class="hljs-keyword">if</span> (_.<span class="hljs-title function_">isFunction</span>(iteratee)) <span class="hljs-keyword">return</span> iteratee;
|
||
<span class="hljs-keyword">if</span> (_.<span class="hljs-title function_">isObject</span>(iteratee) && !instance.<span class="hljs-title function_">_isModel</span>(iteratee)) <span class="hljs-keyword">return</span> <span class="hljs-title function_">modelMatcher</span>(iteratee);
|
||
<span class="hljs-keyword">if</span> (_.<span class="hljs-title function_">isString</span>(iteratee)) <span class="hljs-keyword">return</span> <span class="hljs-keyword">function</span>(<span class="hljs-params">model</span>) { <span class="hljs-keyword">return</span> model.<span class="hljs-title function_">get</span>(iteratee); };
|
||
<span class="hljs-keyword">return</span> iteratee;
|
||
};
|
||
<span class="hljs-keyword">var</span> modelMatcher = <span class="hljs-keyword">function</span>(<span class="hljs-params">attrs</span>) {
|
||
<span class="hljs-keyword">var</span> matcher = _.<span class="hljs-title function_">matches</span>(attrs);
|
||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">function</span>(<span class="hljs-params">model</span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-title function_">matcher</span>(model.<span class="hljs-property">attributes</span>);
|
||
};
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-193">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-193">§</a>
|
||
</div>
|
||
<p>Underscore methods that we want to implement on the Collection.
|
||
90% of the core usefulness of Backbone Collections is actually implemented
|
||
right here:</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> collectionMethods = {<span class="hljs-attr">forEach</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">each</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">map</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">collect</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">reduce</span>: <span class="hljs-number">0</span>,
|
||
<span class="hljs-attr">foldl</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">inject</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">reduceRight</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">foldr</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">find</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">detect</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">filter</span>: <span class="hljs-number">3</span>,
|
||
<span class="hljs-attr">select</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">reject</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">every</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">all</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">some</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">any</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">include</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">includes</span>: <span class="hljs-number">3</span>,
|
||
<span class="hljs-attr">contains</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">invoke</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">max</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">min</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">toArray</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">size</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">first</span>: <span class="hljs-number">3</span>,
|
||
<span class="hljs-attr">head</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">take</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">initial</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">rest</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">tail</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">drop</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">last</span>: <span class="hljs-number">3</span>,
|
||
<span class="hljs-attr">without</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">difference</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">indexOf</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">shuffle</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">lastIndexOf</span>: <span class="hljs-number">3</span>,
|
||
<span class="hljs-attr">isEmpty</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">chain</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">sample</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">partition</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">groupBy</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">countBy</span>: <span class="hljs-number">3</span>,
|
||
<span class="hljs-attr">sortBy</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">indexBy</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">findIndex</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">findLastIndex</span>: <span class="hljs-number">3</span>};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-194">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-194">§</a>
|
||
</div>
|
||
<p>Underscore methods that we want to implement on the Model, mapped to the
|
||
number of arguments they take.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> modelMethods = {<span class="hljs-attr">keys</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">values</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">pairs</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">invert</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">pick</span>: <span class="hljs-number">0</span>,
|
||
<span class="hljs-attr">omit</span>: <span class="hljs-number">0</span>, <span class="hljs-attr">chain</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">isEmpty</span>: <span class="hljs-number">1</span>};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-195">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-195">§</a>
|
||
</div>
|
||
<p>Mix in each Underscore method as a proxy to <code>Collection#models</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre>
|
||
_.<span class="hljs-title function_">each</span>([
|
||
[<span class="hljs-title class_">Collection</span>, collectionMethods, <span class="hljs-string">'models'</span>],
|
||
[<span class="hljs-title class_">Model</span>, modelMethods, <span class="hljs-string">'attributes'</span>]
|
||
], <span class="hljs-keyword">function</span>(<span class="hljs-params">config</span>) {
|
||
<span class="hljs-keyword">var</span> <span class="hljs-title class_">Base</span> = config[<span class="hljs-number">0</span>],
|
||
methods = config[<span class="hljs-number">1</span>],
|
||
attribute = config[<span class="hljs-number">2</span>];
|
||
|
||
<span class="hljs-title class_">Base</span>.<span class="hljs-property">mixin</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">obj</span>) {
|
||
<span class="hljs-keyword">var</span> mappings = _.<span class="hljs-title function_">reduce</span>(_.<span class="hljs-title function_">functions</span>(obj), <span class="hljs-keyword">function</span>(<span class="hljs-params">memo, name</span>) {
|
||
memo[name] = <span class="hljs-number">0</span>;
|
||
<span class="hljs-keyword">return</span> memo;
|
||
}, {});
|
||
<span class="hljs-title function_">addUnderscoreMethods</span>(<span class="hljs-title class_">Base</span>, obj, mappings, attribute);
|
||
};
|
||
|
||
<span class="hljs-title function_">addUnderscoreMethods</span>(<span class="hljs-title class_">Base</span>, _, methods, attribute);
|
||
});</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-196">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-196">§</a>
|
||
</div>
|
||
<h2 id="backbonesync">Backbone.sync</h2>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-197">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-197">§</a>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-198">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-198">§</a>
|
||
</div>
|
||
<p>Override this function to change the manner in which Backbone persists
|
||
models to the server. You will be passed the type of request, and the
|
||
model in question. By default, makes a RESTful Ajax request
|
||
to the model’s <code>url()</code>. Some possible customizations could be:</p>
|
||
<ul>
|
||
<li>Use <code>setTimeout</code> to batch rapid-fire updates into a single request.</li>
|
||
<li>Send up the models as XML instead of JSON.</li>
|
||
<li>Persist models via WebSockets instead of Ajax.</li>
|
||
</ul>
|
||
<p>Turn on <code>Backbone.emulateHTTP</code> in order to send <code>PUT</code> and <code>DELETE</code> requests
|
||
as <code>POST</code>, with a <code>_method</code> parameter containing the true HTTP method,
|
||
as well as all requests with the body as <code>application/x-www-form-urlencoded</code>
|
||
instead of <code>application/json</code> with the model in a param named <code>model</code>.
|
||
Useful when interfacing with server-side languages like <strong>PHP</strong> that make
|
||
it difficult to read the body of <code>PUT</code> requests.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-title class_">Backbone</span>.<span class="hljs-property">sync</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">method, model, options</span>) {
|
||
<span class="hljs-keyword">var</span> type = methodMap[method];</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-199">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-199">§</a>
|
||
</div>
|
||
<p>Default options, unless specified.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _.<span class="hljs-title function_">defaults</span>(options || (options = {}), {
|
||
<span class="hljs-attr">emulateHTTP</span>: <span class="hljs-title class_">Backbone</span>.<span class="hljs-property">emulateHTTP</span>,
|
||
<span class="hljs-attr">emulateJSON</span>: <span class="hljs-title class_">Backbone</span>.<span class="hljs-property">emulateJSON</span>
|
||
});</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-200">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-200">§</a>
|
||
</div>
|
||
<p>Default JSON-request options.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> params = {<span class="hljs-attr">type</span>: type, <span class="hljs-attr">dataType</span>: <span class="hljs-string">'json'</span>};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-201">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-201">§</a>
|
||
</div>
|
||
<p>Ensure that we have a URL.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!options.<span class="hljs-property">url</span>) {
|
||
params.<span class="hljs-property">url</span> = _.<span class="hljs-title function_">result</span>(model, <span class="hljs-string">'url'</span>) || <span class="hljs-title function_">urlError</span>();
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-202">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-202">§</a>
|
||
</div>
|
||
<p>Ensure that we have the appropriate request data.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (options.<span class="hljs-property">data</span> == <span class="hljs-literal">null</span> && model && (method === <span class="hljs-string">'create'</span> || method === <span class="hljs-string">'update'</span> || method === <span class="hljs-string">'patch'</span>)) {
|
||
params.<span class="hljs-property">contentType</span> = <span class="hljs-string">'application/json'</span>;
|
||
params.<span class="hljs-property">data</span> = <span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">stringify</span>(options.<span class="hljs-property">attrs</span> || model.<span class="hljs-title function_">toJSON</span>(options));
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-203">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-203">§</a>
|
||
</div>
|
||
<p>For older servers, emulate JSON by encoding the request into an HTML-form.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (options.<span class="hljs-property">emulateJSON</span>) {
|
||
params.<span class="hljs-property">contentType</span> = <span class="hljs-string">'application/x-www-form-urlencoded'</span>;
|
||
params.<span class="hljs-property">data</span> = params.<span class="hljs-property">data</span> ? {<span class="hljs-attr">model</span>: params.<span class="hljs-property">data</span>} : {};
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-204">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-204">§</a>
|
||
</div>
|
||
<p>For older servers, emulate HTTP by mimicking the HTTP method with <code>_method</code>
|
||
And an <code>X-HTTP-Method-Override</code> header.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (options.<span class="hljs-property">emulateHTTP</span> && (type === <span class="hljs-string">'PUT'</span> || type === <span class="hljs-string">'DELETE'</span> || type === <span class="hljs-string">'PATCH'</span>)) {
|
||
params.<span class="hljs-property">type</span> = <span class="hljs-string">'POST'</span>;
|
||
<span class="hljs-keyword">if</span> (options.<span class="hljs-property">emulateJSON</span>) params.<span class="hljs-property">data</span>.<span class="hljs-property">_method</span> = type;
|
||
<span class="hljs-keyword">var</span> beforeSend = options.<span class="hljs-property">beforeSend</span>;
|
||
options.<span class="hljs-property">beforeSend</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">xhr</span>) {
|
||
xhr.<span class="hljs-title function_">setRequestHeader</span>(<span class="hljs-string">'X-HTTP-Method-Override'</span>, type);
|
||
<span class="hljs-keyword">if</span> (beforeSend) <span class="hljs-keyword">return</span> beforeSend.<span class="hljs-title function_">apply</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-variable language_">arguments</span>);
|
||
};
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-205">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-205">§</a>
|
||
</div>
|
||
<p>Don’t process data on a non-GET request.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (params.<span class="hljs-property">type</span> !== <span class="hljs-string">'GET'</span> && !options.<span class="hljs-property">emulateJSON</span>) {
|
||
params.<span class="hljs-property">processData</span> = <span class="hljs-literal">false</span>;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-206">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-206">§</a>
|
||
</div>
|
||
<p>Pass along <code>textStatus</code> and <code>errorThrown</code> from jQuery.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> error = options.<span class="hljs-property">error</span>;
|
||
options.<span class="hljs-property">error</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">xhr, textStatus, errorThrown</span>) {
|
||
options.<span class="hljs-property">textStatus</span> = textStatus;
|
||
options.<span class="hljs-property">errorThrown</span> = errorThrown;
|
||
<span class="hljs-keyword">if</span> (error) error.<span class="hljs-title function_">call</span>(options.<span class="hljs-property">context</span>, xhr, textStatus, errorThrown);
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-207">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-207">§</a>
|
||
</div>
|
||
<p>Make the request, allowing the user to override any Ajax options.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> xhr = options.<span class="hljs-property">xhr</span> = <span class="hljs-title class_">Backbone</span>.<span class="hljs-title function_">ajax</span>(_.<span class="hljs-title function_">extend</span>(params, options));
|
||
model.<span class="hljs-title function_">trigger</span>(<span class="hljs-string">'request'</span>, model, xhr, options);
|
||
<span class="hljs-keyword">return</span> xhr;
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-208">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-208">§</a>
|
||
</div>
|
||
<p>Map from CRUD to HTTP for our default <code>Backbone.sync</code> implementation.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> methodMap = {
|
||
<span class="hljs-string">'create'</span>: <span class="hljs-string">'POST'</span>,
|
||
<span class="hljs-string">'update'</span>: <span class="hljs-string">'PUT'</span>,
|
||
<span class="hljs-string">'patch'</span>: <span class="hljs-string">'PATCH'</span>,
|
||
<span class="hljs-string">'delete'</span>: <span class="hljs-string">'DELETE'</span>,
|
||
<span class="hljs-string">'read'</span>: <span class="hljs-string">'GET'</span>
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-209">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-209">§</a>
|
||
</div>
|
||
<p>Set the default implementation of <code>Backbone.ajax</code> to proxy through to <code>$</code>.
|
||
Override this if you’d like to use a different library.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-title class_">Backbone</span>.<span class="hljs-property">ajax</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-title class_">Backbone</span>.<span class="hljs-property">$</span>.<span class="hljs-property">ajax</span>.<span class="hljs-title function_">apply</span>(<span class="hljs-title class_">Backbone</span>.<span class="hljs-property">$</span>, <span class="hljs-variable language_">arguments</span>);
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-210">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-210">§</a>
|
||
</div>
|
||
<h2 id="backbonerouter">Backbone.Router</h2>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-211">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-211">§</a>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-212">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-212">§</a>
|
||
</div>
|
||
<p>Routers map faux-URLs to actions, and fire events when routes are
|
||
matched. Creating a new one sets its <code>routes</code> hash, if not set statically.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> <span class="hljs-title class_">Router</span> = <span class="hljs-title class_">Backbone</span>.<span class="hljs-property">Router</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">options</span>) {
|
||
options || (options = {});
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">preinitialize</span>.<span class="hljs-title function_">apply</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-variable language_">arguments</span>);
|
||
<span class="hljs-keyword">if</span> (options.<span class="hljs-property">routes</span>) <span class="hljs-variable language_">this</span>.<span class="hljs-property">routes</span> = options.<span class="hljs-property">routes</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_bindRoutes</span>();
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">initialize</span>.<span class="hljs-title function_">apply</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-variable language_">arguments</span>);
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-213">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-213">§</a>
|
||
</div>
|
||
<p>Cached regular expressions for matching named param parts and splatted
|
||
parts of route strings.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> optionalParam = <span class="hljs-regexp">/\((.*?)\)/g</span>;
|
||
<span class="hljs-keyword">var</span> namedParam = <span class="hljs-regexp">/(\(\?)?:\w+/g</span>;
|
||
<span class="hljs-keyword">var</span> splatParam = <span class="hljs-regexp">/\*\w+/g</span>;
|
||
<span class="hljs-keyword">var</span> escapeRegExp = <span class="hljs-regexp">/[\-{}\[\]+?.,\\\^$|#\s]/g</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-214">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-214">§</a>
|
||
</div>
|
||
<p>Set up all inheritable <strong>Backbone.Router</strong> properties and methods.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _.<span class="hljs-title function_">extend</span>(<span class="hljs-title class_">Router</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>, <span class="hljs-title class_">Events</span>, {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-215">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-215">§</a>
|
||
</div>
|
||
<p>preinitialize is an empty function by default. You can override it with a function
|
||
or object. preinitialize will run before any instantiation logic is run in the Router.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">preinitialize</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-216">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-216">§</a>
|
||
</div>
|
||
<p>Initialize is an empty function by default. Override it with your own
|
||
initialization logic.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">initialize</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-217">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-217">§</a>
|
||
</div>
|
||
<p>Manually bind a single named route to a callback. For example:</p>
|
||
<pre><code><span class="hljs-variable language_">this</span>.<span class="hljs-title function_">route</span>(<span class="hljs-string">'search/:query/p:num'</span>, <span class="hljs-string">'search'</span>, <span class="hljs-keyword">function</span>(<span class="hljs-params">query, num</span>) {
|
||
...
|
||
});
|
||
</code></pre>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">route</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">route, name, callback</span>) {
|
||
<span class="hljs-keyword">if</span> (!_.<span class="hljs-title function_">isRegExp</span>(route)) route = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_routeToRegExp</span>(route);
|
||
<span class="hljs-keyword">if</span> (_.<span class="hljs-title function_">isFunction</span>(name)) {
|
||
callback = name;
|
||
name = <span class="hljs-string">''</span>;
|
||
}
|
||
<span class="hljs-keyword">if</span> (!callback) callback = <span class="hljs-variable language_">this</span>[name];
|
||
<span class="hljs-keyword">var</span> router = <span class="hljs-variable language_">this</span>;
|
||
<span class="hljs-title class_">Backbone</span>.<span class="hljs-property">history</span>.<span class="hljs-title function_">route</span>(route, <span class="hljs-keyword">function</span>(<span class="hljs-params">fragment</span>) {
|
||
<span class="hljs-keyword">var</span> args = router.<span class="hljs-title function_">_extractParameters</span>(route, fragment);
|
||
<span class="hljs-keyword">if</span> (router.<span class="hljs-title function_">execute</span>(callback, args, name) !== <span class="hljs-literal">false</span>) {
|
||
router.<span class="hljs-property">trigger</span>.<span class="hljs-title function_">apply</span>(router, [<span class="hljs-string">'route:'</span> + name].<span class="hljs-title function_">concat</span>(args));
|
||
router.<span class="hljs-title function_">trigger</span>(<span class="hljs-string">'route'</span>, name, args);
|
||
<span class="hljs-title class_">Backbone</span>.<span class="hljs-property">history</span>.<span class="hljs-title function_">trigger</span>(<span class="hljs-string">'route'</span>, router, name, args);
|
||
}
|
||
});
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-218">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-218">§</a>
|
||
</div>
|
||
<p>Execute a route handler with the provided parameters. This is an
|
||
excellent place to do pre-route setup or post-route cleanup.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">execute</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">callback, args, name</span>) {
|
||
<span class="hljs-keyword">if</span> (callback) callback.<span class="hljs-title function_">apply</span>(<span class="hljs-variable language_">this</span>, args);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-219">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-219">§</a>
|
||
</div>
|
||
<p>Simple proxy to <code>Backbone.history</code> to save a fragment into the history.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">navigate</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">fragment, options</span>) {
|
||
<span class="hljs-title class_">Backbone</span>.<span class="hljs-property">history</span>.<span class="hljs-title function_">navigate</span>(fragment, options);
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-220">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-220">§</a>
|
||
</div>
|
||
<p>Bind all defined routes to <code>Backbone.history</code>. We have to reverse the
|
||
order of the routes here to support behavior where the most general
|
||
routes can be defined at the bottom of the route map.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">_bindRoutes</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">if</span> (!<span class="hljs-variable language_">this</span>.<span class="hljs-property">routes</span>) <span class="hljs-keyword">return</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">routes</span> = _.<span class="hljs-title function_">result</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-string">'routes'</span>);
|
||
<span class="hljs-keyword">var</span> route, routes = _.<span class="hljs-title function_">keys</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">routes</span>);
|
||
<span class="hljs-keyword">while</span> ((route = routes.<span class="hljs-title function_">pop</span>()) != <span class="hljs-literal">null</span>) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">route</span>(route, <span class="hljs-variable language_">this</span>.<span class="hljs-property">routes</span>[route]);
|
||
}
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-221">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-221">§</a>
|
||
</div>
|
||
<p>Convert a route string into a regular expression, suitable for matching
|
||
against the current location hash.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">_routeToRegExp</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">route</span>) {
|
||
route = route.<span class="hljs-title function_">replace</span>(escapeRegExp, <span class="hljs-string">'\\$&'</span>)
|
||
.<span class="hljs-title function_">replace</span>(optionalParam, <span class="hljs-string">'(?:$1)?'</span>)
|
||
.<span class="hljs-title function_">replace</span>(namedParam, <span class="hljs-keyword">function</span>(<span class="hljs-params">match, optional</span>) {
|
||
<span class="hljs-keyword">return</span> optional ? match : <span class="hljs-string">'([^/?]+)'</span>;
|
||
})
|
||
.<span class="hljs-title function_">replace</span>(splatParam, <span class="hljs-string">'([^?]*?)'</span>);
|
||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">RegExp</span>(<span class="hljs-string">'^'</span> + route + <span class="hljs-string">'(?:\\?([\\s\\S]*))?$'</span>);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-222">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-222">§</a>
|
||
</div>
|
||
<p>Given a route, and a URL fragment that it matches, return the array of
|
||
extracted decoded parameters. Empty or unmatched parameters will be
|
||
treated as <code>null</code> to normalize cross-browser behavior.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">_extractParameters</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">route, fragment</span>) {
|
||
<span class="hljs-keyword">var</span> params = route.<span class="hljs-title function_">exec</span>(fragment).<span class="hljs-title function_">slice</span>(<span class="hljs-number">1</span>);
|
||
<span class="hljs-keyword">return</span> _.<span class="hljs-title function_">map</span>(params, <span class="hljs-keyword">function</span>(<span class="hljs-params">param, i</span>) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-223">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-223">§</a>
|
||
</div>
|
||
<p>Don’t decode the search params.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (i === params.<span class="hljs-property">length</span> - <span class="hljs-number">1</span>) <span class="hljs-keyword">return</span> param || <span class="hljs-literal">null</span>;
|
||
<span class="hljs-keyword">return</span> param ? <span class="hljs-built_in">decodeURIComponent</span>(param) : <span class="hljs-literal">null</span>;
|
||
});
|
||
}
|
||
|
||
});</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-224">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-224">§</a>
|
||
</div>
|
||
<h2 id="backbonehistory">Backbone.History</h2>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-225">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-225">§</a>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-226">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-226">§</a>
|
||
</div>
|
||
<p>Handles cross-browser history management, based on either
|
||
<a href="http://diveintohtml5.info/history.html">pushState</a> and real URLs, or
|
||
<a href="https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange">onhashchange</a>
|
||
and URL fragments. If the browser supports neither (old IE, natch),
|
||
falls back to polling.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> <span class="hljs-title class_">History</span> = <span class="hljs-title class_">Backbone</span>.<span class="hljs-property">History</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">handlers</span> = [];
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">checkUrl</span> = <span class="hljs-variable language_">this</span>.<span class="hljs-property">checkUrl</span>.<span class="hljs-title function_">bind</span>(<span class="hljs-variable language_">this</span>);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-227">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-227">§</a>
|
||
</div>
|
||
<p>Ensure that <code>History</code> can be used outside of the browser.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">typeof</span> <span class="hljs-variable language_">window</span> !== <span class="hljs-string">'undefined'</span>) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">location</span> = <span class="hljs-variable language_">window</span>.<span class="hljs-property">location</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">history</span> = <span class="hljs-variable language_">window</span>.<span class="hljs-property">history</span>;
|
||
}
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-228">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-228">§</a>
|
||
</div>
|
||
<p>Cached regex for stripping a leading hash/slash and trailing space.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> routeStripper = <span class="hljs-regexp">/^[#\/]|\s+$/g</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-229">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-229">§</a>
|
||
</div>
|
||
<p>Cached regex for stripping leading and trailing slashes.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> rootStripper = <span class="hljs-regexp">/^\/+|\/+$/g</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-230">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-230">§</a>
|
||
</div>
|
||
<p>Cached regex for stripping urls of hash.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> pathStripper = <span class="hljs-regexp">/#.*$/</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-231">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-231">§</a>
|
||
</div>
|
||
<p>Has the history handling already been started?</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-title class_">History</span>.<span class="hljs-property">started</span> = <span class="hljs-literal">false</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-232">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-232">§</a>
|
||
</div>
|
||
<p>Set up all inheritable <strong>Backbone.History</strong> properties and methods.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _.<span class="hljs-title function_">extend</span>(<span class="hljs-title class_">History</span>.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>, <span class="hljs-title class_">Events</span>, {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-233">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-233">§</a>
|
||
</div>
|
||
<p>The default interval to poll for hash changes, if necessary, is
|
||
twenty times a second.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">interval</span>: <span class="hljs-number">50</span>,</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-234">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-234">§</a>
|
||
</div>
|
||
<p>Are we at the app root?</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">atRoot</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">var</span> path = <span class="hljs-variable language_">this</span>.<span class="hljs-property">location</span>.<span class="hljs-property">pathname</span>.<span class="hljs-title function_">replace</span>(<span class="hljs-regexp">/[^\/]$/</span>, <span class="hljs-string">'$&/'</span>);
|
||
<span class="hljs-keyword">return</span> path === <span class="hljs-variable language_">this</span>.<span class="hljs-property">root</span> && !<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">getSearch</span>();
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-235">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-235">§</a>
|
||
</div>
|
||
<p>Does the pathname match the root?</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">matchRoot</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">var</span> path = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">decodeFragment</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">location</span>.<span class="hljs-property">pathname</span>);
|
||
<span class="hljs-keyword">var</span> rootPath = path.<span class="hljs-title function_">slice</span>(<span class="hljs-number">0</span>, <span class="hljs-variable language_">this</span>.<span class="hljs-property">root</span>.<span class="hljs-property">length</span> - <span class="hljs-number">1</span>) + <span class="hljs-string">'/'</span>;
|
||
<span class="hljs-keyword">return</span> rootPath === <span class="hljs-variable language_">this</span>.<span class="hljs-property">root</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-236">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-236">§</a>
|
||
</div>
|
||
<p>Unicode characters in <code>location.pathname</code> are percent encoded so they’re
|
||
decoded for comparison. <code>%25</code> should not be decoded since it may be part
|
||
of an encoded parameter.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">decodeFragment</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">fragment</span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-built_in">decodeURI</span>(fragment.<span class="hljs-title function_">replace</span>(<span class="hljs-regexp">/%25/g</span>, <span class="hljs-string">'%2525'</span>));
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-237">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-237">§</a>
|
||
</div>
|
||
<p>In IE6, the hash fragment and search params are incorrect if the
|
||
fragment contains <code>?</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">getSearch</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">var</span> match = <span class="hljs-variable language_">this</span>.<span class="hljs-property">location</span>.<span class="hljs-property">href</span>.<span class="hljs-title function_">replace</span>(<span class="hljs-regexp">/#.*/</span>, <span class="hljs-string">''</span>).<span class="hljs-title function_">match</span>(<span class="hljs-regexp">/\?.+/</span>);
|
||
<span class="hljs-keyword">return</span> match ? match[<span class="hljs-number">0</span>] : <span class="hljs-string">''</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-238">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-238">§</a>
|
||
</div>
|
||
<p>Gets the true hash value. Cannot use location.hash directly due to bug
|
||
in Firefox where location.hash will always be decoded.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">getHash</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"><span class="hljs-variable language_">window</span></span>) {
|
||
<span class="hljs-keyword">var</span> match = (<span class="hljs-variable language_">window</span> || <span class="hljs-variable language_">this</span>).<span class="hljs-property">location</span>.<span class="hljs-property">href</span>.<span class="hljs-title function_">match</span>(<span class="hljs-regexp">/#(.*)$/</span>);
|
||
<span class="hljs-keyword">return</span> match ? match[<span class="hljs-number">1</span>] : <span class="hljs-string">''</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-239">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-239">§</a>
|
||
</div>
|
||
<p>Get the pathname and search params, without the root.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">getPath</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">var</span> path = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">decodeFragment</span>(
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">location</span>.<span class="hljs-property">pathname</span> + <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">getSearch</span>()
|
||
).<span class="hljs-title function_">slice</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">root</span>.<span class="hljs-property">length</span> - <span class="hljs-number">1</span>);
|
||
<span class="hljs-keyword">return</span> path.<span class="hljs-title function_">charAt</span>(<span class="hljs-number">0</span>) === <span class="hljs-string">'/'</span> ? path.<span class="hljs-title function_">slice</span>(<span class="hljs-number">1</span>) : path;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-240">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-240">§</a>
|
||
</div>
|
||
<p>Get the cross-browser normalized URL fragment from the path or hash.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">getFragment</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">fragment</span>) {
|
||
<span class="hljs-keyword">if</span> (fragment == <span class="hljs-literal">null</span>) {
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">_usePushState</span> || !<span class="hljs-variable language_">this</span>.<span class="hljs-property">_wantsHashChange</span>) {
|
||
fragment = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">getPath</span>();
|
||
} <span class="hljs-keyword">else</span> {
|
||
fragment = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">getHash</span>();
|
||
}
|
||
}
|
||
<span class="hljs-keyword">return</span> fragment.<span class="hljs-title function_">replace</span>(routeStripper, <span class="hljs-string">''</span>);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-241">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-241">§</a>
|
||
</div>
|
||
<p>Start the hash change handling, returning <code>true</code> if the current URL matches
|
||
an existing route, and <code>false</code> otherwise.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">start</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">options</span>) {
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-title class_">History</span>.<span class="hljs-property">started</span>) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Error</span>(<span class="hljs-string">'Backbone.history has already been started'</span>);
|
||
<span class="hljs-title class_">History</span>.<span class="hljs-property">started</span> = <span class="hljs-literal">true</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-242">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-242">§</a>
|
||
</div>
|
||
<p>Figure out the initial configuration. Do we need an iframe?
|
||
Is pushState desired … is it available?</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-variable language_">this</span>.<span class="hljs-property">options</span> = _.<span class="hljs-title function_">extend</span>({<span class="hljs-attr">root</span>: <span class="hljs-string">'/'</span>}, <span class="hljs-variable language_">this</span>.<span class="hljs-property">options</span>, options);
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">root</span> = <span class="hljs-variable language_">this</span>.<span class="hljs-property">options</span>.<span class="hljs-property">root</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_trailingSlash</span> = <span class="hljs-variable language_">this</span>.<span class="hljs-property">options</span>.<span class="hljs-property">trailingSlash</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_wantsHashChange</span> = <span class="hljs-variable language_">this</span>.<span class="hljs-property">options</span>.<span class="hljs-property">hashChange</span> !== <span class="hljs-literal">false</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_hasHashChange</span> = <span class="hljs-string">'onhashchange'</span> <span class="hljs-keyword">in</span> <span class="hljs-variable language_">window</span> && (<span class="hljs-variable language_">document</span>.<span class="hljs-property">documentMode</span> === <span class="hljs-keyword">void</span> <span class="hljs-number">0</span> || <span class="hljs-variable language_">document</span>.<span class="hljs-property">documentMode</span> > <span class="hljs-number">7</span>);
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_useHashChange</span> = <span class="hljs-variable language_">this</span>.<span class="hljs-property">_wantsHashChange</span> && <span class="hljs-variable language_">this</span>.<span class="hljs-property">_hasHashChange</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_wantsPushState</span> = !!<span class="hljs-variable language_">this</span>.<span class="hljs-property">options</span>.<span class="hljs-property">pushState</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_hasPushState</span> = !!(<span class="hljs-variable language_">this</span>.<span class="hljs-property">history</span> && <span class="hljs-variable language_">this</span>.<span class="hljs-property">history</span>.<span class="hljs-property">pushState</span>);
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_usePushState</span> = <span class="hljs-variable language_">this</span>.<span class="hljs-property">_wantsPushState</span> && <span class="hljs-variable language_">this</span>.<span class="hljs-property">_hasPushState</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">fragment</span> = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">getFragment</span>();</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-243">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-243">§</a>
|
||
</div>
|
||
<p>Normalize root to always include a leading and trailing slash.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-variable language_">this</span>.<span class="hljs-property">root</span> = (<span class="hljs-string">'/'</span> + <span class="hljs-variable language_">this</span>.<span class="hljs-property">root</span> + <span class="hljs-string">'/'</span>).<span class="hljs-title function_">replace</span>(rootStripper, <span class="hljs-string">'/'</span>);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-244">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-244">§</a>
|
||
</div>
|
||
<p>Transition from hashChange to pushState or vice versa if both are
|
||
requested.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">_wantsHashChange</span> && <span class="hljs-variable language_">this</span>.<span class="hljs-property">_wantsPushState</span>) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-245">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-245">§</a>
|
||
</div>
|
||
<p>If we’ve started off with a route from a <code>pushState</code>-enabled
|
||
browser, but we’re currently in a browser that doesn’t support it…</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!<span class="hljs-variable language_">this</span>.<span class="hljs-property">_hasPushState</span> && !<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">atRoot</span>()) {
|
||
<span class="hljs-keyword">var</span> rootPath = <span class="hljs-variable language_">this</span>.<span class="hljs-property">root</span>.<span class="hljs-title function_">slice</span>(<span class="hljs-number">0</span>, -<span class="hljs-number">1</span>) || <span class="hljs-string">'/'</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">location</span>.<span class="hljs-title function_">replace</span>(rootPath + <span class="hljs-string">'#'</span> + <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">getPath</span>());</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-246">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-246">§</a>
|
||
</div>
|
||
<p>Return immediately as browser will do redirect to new url</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-247">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-247">§</a>
|
||
</div>
|
||
<p>Or if we’ve started out with a hash-based route, but we’re currently
|
||
in a browser where it could be <code>pushState</code>-based instead…</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">_hasPushState</span> && <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">atRoot</span>()) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">navigate</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">getHash</span>(), {<span class="hljs-attr">replace</span>: <span class="hljs-literal">true</span>});
|
||
}
|
||
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-248">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-248">§</a>
|
||
</div>
|
||
<p>Proxy an iframe to handle location events if the browser doesn’t
|
||
support the <code>hashchange</code> event, HTML5 history, or the user wants
|
||
<code>hashChange</code> but not <code>pushState</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!<span class="hljs-variable language_">this</span>.<span class="hljs-property">_hasHashChange</span> && <span class="hljs-variable language_">this</span>.<span class="hljs-property">_wantsHashChange</span> && !<span class="hljs-variable language_">this</span>.<span class="hljs-property">_usePushState</span>) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">iframe</span> = <span class="hljs-variable language_">document</span>.<span class="hljs-title function_">createElement</span>(<span class="hljs-string">'iframe'</span>);
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">iframe</span>.<span class="hljs-property">src</span> = <span class="hljs-string">'javascript:0'</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">iframe</span>.<span class="hljs-property">style</span>.<span class="hljs-property">display</span> = <span class="hljs-string">'none'</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">iframe</span>.<span class="hljs-property">tabIndex</span> = -<span class="hljs-number">1</span>;
|
||
<span class="hljs-keyword">var</span> body = <span class="hljs-variable language_">document</span>.<span class="hljs-property">body</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-249">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-249">§</a>
|
||
</div>
|
||
<p>Using <code>appendChild</code> will throw on IE < 9 if the document is not ready.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> iWindow = body.<span class="hljs-title function_">insertBefore</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">iframe</span>, body.<span class="hljs-property">firstChild</span>).<span class="hljs-property">contentWindow</span>;
|
||
iWindow.<span class="hljs-property">document</span>.<span class="hljs-title function_">open</span>();
|
||
iWindow.<span class="hljs-property">document</span>.<span class="hljs-title function_">close</span>();
|
||
iWindow.<span class="hljs-property">location</span>.<span class="hljs-property">hash</span> = <span class="hljs-string">'#'</span> + <span class="hljs-variable language_">this</span>.<span class="hljs-property">fragment</span>;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-250">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-250">§</a>
|
||
</div>
|
||
<p>Add a cross-platform <code>addEventListener</code> shim for older browsers.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> addEventListener = <span class="hljs-variable language_">window</span>.<span class="hljs-property">addEventListener</span> || <span class="hljs-keyword">function</span>(<span class="hljs-params">eventName, listener</span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-title function_">attachEvent</span>(<span class="hljs-string">'on'</span> + eventName, listener);
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-251">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-251">§</a>
|
||
</div>
|
||
<p>Depending on whether we’re using pushState or hashes, and whether
|
||
‘onhashchange’ is supported, determine how we check the URL state.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">_usePushState</span>) {
|
||
<span class="hljs-title function_">addEventListener</span>(<span class="hljs-string">'popstate'</span>, <span class="hljs-variable language_">this</span>.<span class="hljs-property">checkUrl</span>, <span class="hljs-literal">false</span>);
|
||
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">_useHashChange</span> && !<span class="hljs-variable language_">this</span>.<span class="hljs-property">iframe</span>) {
|
||
<span class="hljs-title function_">addEventListener</span>(<span class="hljs-string">'hashchange'</span>, <span class="hljs-variable language_">this</span>.<span class="hljs-property">checkUrl</span>, <span class="hljs-literal">false</span>);
|
||
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">_wantsHashChange</span>) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">_checkUrlInterval</span> = <span class="hljs-built_in">setInterval</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">checkUrl</span>, <span class="hljs-variable language_">this</span>.<span class="hljs-property">interval</span>);
|
||
}
|
||
|
||
<span class="hljs-keyword">if</span> (!<span class="hljs-variable language_">this</span>.<span class="hljs-property">options</span>.<span class="hljs-property">silent</span>) <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">loadUrl</span>();
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-252">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-252">§</a>
|
||
</div>
|
||
<p>Disable Backbone.history, perhaps temporarily. Not useful in a real app,
|
||
but possibly useful for unit testing Routers.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">stop</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-253">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-253">§</a>
|
||
</div>
|
||
<p>Add a cross-platform <code>removeEventListener</code> shim for older browsers.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> removeEventListener = <span class="hljs-variable language_">window</span>.<span class="hljs-property">removeEventListener</span> || <span class="hljs-keyword">function</span>(<span class="hljs-params">eventName, listener</span>) {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-title function_">detachEvent</span>(<span class="hljs-string">'on'</span> + eventName, listener);
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-254">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-254">§</a>
|
||
</div>
|
||
<p>Remove window listeners.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">_usePushState</span>) {
|
||
<span class="hljs-title function_">removeEventListener</span>(<span class="hljs-string">'popstate'</span>, <span class="hljs-variable language_">this</span>.<span class="hljs-property">checkUrl</span>, <span class="hljs-literal">false</span>);
|
||
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">_useHashChange</span> && !<span class="hljs-variable language_">this</span>.<span class="hljs-property">iframe</span>) {
|
||
<span class="hljs-title function_">removeEventListener</span>(<span class="hljs-string">'hashchange'</span>, <span class="hljs-variable language_">this</span>.<span class="hljs-property">checkUrl</span>, <span class="hljs-literal">false</span>);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-255">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-255">§</a>
|
||
</div>
|
||
<p>Clean up the iframe if necessary.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">iframe</span>) {
|
||
<span class="hljs-variable language_">document</span>.<span class="hljs-property">body</span>.<span class="hljs-title function_">removeChild</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">iframe</span>);
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">iframe</span> = <span class="hljs-literal">null</span>;
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-256">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-256">§</a>
|
||
</div>
|
||
<p>Some environments will throw when clearing an undefined interval.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">_checkUrlInterval</span>) <span class="hljs-built_in">clearInterval</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">_checkUrlInterval</span>);
|
||
<span class="hljs-title class_">History</span>.<span class="hljs-property">started</span> = <span class="hljs-literal">false</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-257">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-257">§</a>
|
||
</div>
|
||
<p>Add a route to be tested when the fragment changes. Routes added later
|
||
may override previous routes.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">route</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">route, callback</span>) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">handlers</span>.<span class="hljs-title function_">unshift</span>({<span class="hljs-attr">route</span>: route, <span class="hljs-attr">callback</span>: callback});
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-258">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-258">§</a>
|
||
</div>
|
||
<p>Checks the current URL to see if it has changed, and if it has,
|
||
calls <code>loadUrl</code>, normalizing across the hidden iframe.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">checkUrl</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) {
|
||
<span class="hljs-keyword">var</span> current = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">getFragment</span>();</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-259">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-259">§</a>
|
||
</div>
|
||
<p>If the user pressed the back button, the iframe’s hash will have
|
||
changed and we should use that for comparison.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (current === <span class="hljs-variable language_">this</span>.<span class="hljs-property">fragment</span> && <span class="hljs-variable language_">this</span>.<span class="hljs-property">iframe</span>) {
|
||
current = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">getHash</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">iframe</span>.<span class="hljs-property">contentWindow</span>);
|
||
}
|
||
|
||
<span class="hljs-keyword">if</span> (current === <span class="hljs-variable language_">this</span>.<span class="hljs-property">fragment</span>) {
|
||
<span class="hljs-keyword">if</span> (!<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">matchRoot</span>()) <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">notfound</span>();
|
||
<span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
|
||
}
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">iframe</span>) <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">navigate</span>(current);
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">loadUrl</span>();
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-260">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-260">§</a>
|
||
</div>
|
||
<p>Attempt to load the current URL fragment. If a route succeeds with a
|
||
match, returns <code>true</code>. If no defined routes matches the fragment,
|
||
returns <code>false</code>.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">loadUrl</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">fragment</span>) {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-261">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-261">§</a>
|
||
</div>
|
||
<p>If the root doesn’t match, no routes can match either.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">matchRoot</span>()) <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">notfound</span>();
|
||
fragment = <span class="hljs-variable language_">this</span>.<span class="hljs-property">fragment</span> = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">getFragment</span>(fragment);
|
||
<span class="hljs-keyword">return</span> _.<span class="hljs-title function_">some</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">handlers</span>, <span class="hljs-keyword">function</span>(<span class="hljs-params">handler</span>) {
|
||
<span class="hljs-keyword">if</span> (handler.<span class="hljs-property">route</span>.<span class="hljs-title function_">test</span>(fragment)) {
|
||
handler.<span class="hljs-title function_">callback</span>(fragment);
|
||
<span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
|
||
}
|
||
}) || <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">notfound</span>();
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-262">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-262">§</a>
|
||
</div>
|
||
<p>When no route could be matched, this method is called internally to
|
||
trigger the <code>'notfound'</code> event. It returns <code>false</code> so that it can be used
|
||
in tail position.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">notfound</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">trigger</span>(<span class="hljs-string">'notfound'</span>);
|
||
<span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-263">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-263">§</a>
|
||
</div>
|
||
<p>Save a fragment into the hash history, or replace the URL state if the
|
||
‘replace’ option is passed. You are responsible for properly URL-encoding
|
||
the fragment in advance.</p>
|
||
<p>The options object can contain <code>trigger: true</code> if you wish to have the
|
||
route callback be fired (not usually desirable), or <code>replace: true</code>, if
|
||
you wish to modify the current URL without adding an entry to the history.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">navigate</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">fragment, options</span>) {
|
||
<span class="hljs-keyword">if</span> (!<span class="hljs-title class_">History</span>.<span class="hljs-property">started</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
|
||
<span class="hljs-keyword">if</span> (!options || options === <span class="hljs-literal">true</span>) options = {<span class="hljs-attr">trigger</span>: !!options};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-264">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-264">§</a>
|
||
</div>
|
||
<p>Normalize the fragment.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> fragment = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">getFragment</span>(fragment || <span class="hljs-string">''</span>);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-265">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-265">§</a>
|
||
</div>
|
||
<p>Strip trailing slash on the root unless _trailingSlash is true</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> rootPath = <span class="hljs-variable language_">this</span>.<span class="hljs-property">root</span>;
|
||
<span class="hljs-keyword">if</span> (!<span class="hljs-variable language_">this</span>.<span class="hljs-property">_trailingSlash</span> && (fragment === <span class="hljs-string">''</span> || fragment.<span class="hljs-title function_">charAt</span>(<span class="hljs-number">0</span>) === <span class="hljs-string">'?'</span>)) {
|
||
rootPath = rootPath.<span class="hljs-title function_">slice</span>(<span class="hljs-number">0</span>, -<span class="hljs-number">1</span>) || <span class="hljs-string">'/'</span>;
|
||
}
|
||
<span class="hljs-keyword">var</span> url = rootPath + fragment;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-266">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-266">§</a>
|
||
</div>
|
||
<p>Strip the fragment of the query and hash for matching.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> fragment = fragment.<span class="hljs-title function_">replace</span>(pathStripper, <span class="hljs-string">''</span>);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-267">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-267">§</a>
|
||
</div>
|
||
<p>Decode for matching.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> decodedFragment = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">decodeFragment</span>(fragment);
|
||
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">fragment</span> === decodedFragment) <span class="hljs-keyword">return</span>;
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">fragment</span> = decodedFragment;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-268">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-268">§</a>
|
||
</div>
|
||
<p>If pushState is available, we use it to set the fragment as a real URL.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">_usePushState</span>) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-property">history</span>[options.<span class="hljs-property">replace</span> ? <span class="hljs-string">'replaceState'</span> : <span class="hljs-string">'pushState'</span>]({}, <span class="hljs-variable language_">document</span>.<span class="hljs-property">title</span>, url);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-269">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-269">§</a>
|
||
</div>
|
||
<p>If hash changes haven’t been explicitly disabled, update the hash
|
||
fragment to store history.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">_wantsHashChange</span>) {
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_updateHash</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">location</span>, fragment, options.<span class="hljs-property">replace</span>);
|
||
<span class="hljs-keyword">if</span> (<span class="hljs-variable language_">this</span>.<span class="hljs-property">iframe</span> && fragment !== <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">getHash</span>(<span class="hljs-variable language_">this</span>.<span class="hljs-property">iframe</span>.<span class="hljs-property">contentWindow</span>)) {
|
||
<span class="hljs-keyword">var</span> iWindow = <span class="hljs-variable language_">this</span>.<span class="hljs-property">iframe</span>.<span class="hljs-property">contentWindow</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-270">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-270">§</a>
|
||
</div>
|
||
<p>Opening and closing the iframe tricks IE7 and earlier to push a
|
||
history entry on hash-tag change. When replace is true, we don’t
|
||
want this.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (!options.<span class="hljs-property">replace</span>) {
|
||
iWindow.<span class="hljs-property">document</span>.<span class="hljs-title function_">open</span>();
|
||
iWindow.<span class="hljs-property">document</span>.<span class="hljs-title function_">close</span>();
|
||
}
|
||
|
||
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">_updateHash</span>(iWindow.<span class="hljs-property">location</span>, fragment, options.<span class="hljs-property">replace</span>);
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-271">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-271">§</a>
|
||
</div>
|
||
<p>If you’ve told us that you explicitly don’t want fallback hashchange-
|
||
based history, then <code>navigate</code> becomes a page refresh.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> } <span class="hljs-keyword">else</span> {
|
||
<span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-property">location</span>.<span class="hljs-title function_">assign</span>(url);
|
||
}
|
||
<span class="hljs-keyword">if</span> (options.<span class="hljs-property">trigger</span>) <span class="hljs-keyword">return</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">loadUrl</span>(fragment);
|
||
},</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-272">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-272">§</a>
|
||
</div>
|
||
<p>Update the hash location, either replacing the current entry, or adding
|
||
a new one to the browser history.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-attr">_updateHash</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">location, fragment, replace</span>) {
|
||
<span class="hljs-keyword">if</span> (replace) {
|
||
<span class="hljs-keyword">var</span> href = location.<span class="hljs-property">href</span>.<span class="hljs-title function_">replace</span>(<span class="hljs-regexp">/(javascript:|#).*$/</span>, <span class="hljs-string">''</span>);
|
||
location.<span class="hljs-title function_">replace</span>(href + <span class="hljs-string">'#'</span> + fragment);
|
||
} <span class="hljs-keyword">else</span> {</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-273">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-273">§</a>
|
||
</div>
|
||
<p>Some browsers require that <code>hash</code> contains a leading #.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> location.<span class="hljs-property">hash</span> = <span class="hljs-string">'#'</span> + fragment;
|
||
}
|
||
}
|
||
|
||
});</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-274">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-274">§</a>
|
||
</div>
|
||
<p>Create the default Backbone.history.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-title class_">Backbone</span>.<span class="hljs-property">history</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">History</span>;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-275">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-275">§</a>
|
||
</div>
|
||
<h2 id="helpers">Helpers</h2>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-276">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-276">§</a>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-277">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-277">§</a>
|
||
</div>
|
||
<p>Helper function to correctly set up the prototype chain for subclasses.
|
||
Similar to <code>goog.inherits</code>, but uses a hash of prototype properties and
|
||
class properties to be extended.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> extend = <span class="hljs-keyword">function</span>(<span class="hljs-params">protoProps, staticProps</span>) {
|
||
<span class="hljs-keyword">var</span> parent = <span class="hljs-variable language_">this</span>;
|
||
<span class="hljs-keyword">var</span> child;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-278">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-278">§</a>
|
||
</div>
|
||
<p>The constructor function for the new subclass is either defined by you
|
||
(the “constructor” property in your <code>extend</code> definition), or defaulted
|
||
by us to simply call the parent constructor.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">if</span> (protoProps && _.<span class="hljs-title function_">has</span>(protoProps, <span class="hljs-string">'constructor'</span>)) {
|
||
child = protoProps.<span class="hljs-property">constructor</span>;
|
||
} <span class="hljs-keyword">else</span> {
|
||
child = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){ <span class="hljs-keyword">return</span> parent.<span class="hljs-title function_">apply</span>(<span class="hljs-variable language_">this</span>, <span class="hljs-variable language_">arguments</span>); };
|
||
}</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-279">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-279">§</a>
|
||
</div>
|
||
<p>Add static properties to the constructor function, if supplied.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> _.<span class="hljs-title function_">extend</span>(child, parent, staticProps);</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-280">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-280">§</a>
|
||
</div>
|
||
<p>Set the prototype chain to inherit from <code>parent</code>, without calling
|
||
<code>parent</code>‘s constructor function and add the prototype properties.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> child.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span> = _.<span class="hljs-title function_">create</span>(parent.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>, protoProps);
|
||
child.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>.<span class="hljs-property">constructor</span> = child;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-281">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-281">§</a>
|
||
</div>
|
||
<p>Set a convenience property in case the parent’s prototype is needed
|
||
later.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> child.<span class="hljs-property">__super__</span> = parent.<span class="hljs-property"><span class="hljs-keyword">prototype</span></span>;
|
||
|
||
<span class="hljs-keyword">return</span> child;
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-282">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-282">§</a>
|
||
</div>
|
||
<p>Set up inheritance for the model, collection, router, view and history.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-title class_">Model</span>.<span class="hljs-property">extend</span> = <span class="hljs-title class_">Collection</span>.<span class="hljs-property">extend</span> = <span class="hljs-title class_">Router</span>.<span class="hljs-property">extend</span> = <span class="hljs-title class_">View</span>.<span class="hljs-property">extend</span> = <span class="hljs-title class_">History</span>.<span class="hljs-property">extend</span> = extend;</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-283">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-283">§</a>
|
||
</div>
|
||
<p>Throw an error when a URL is needed, and none is supplied.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> urlError = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Error</span>(<span class="hljs-string">'A "url" property or function must be specified'</span>);
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-284">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-284">§</a>
|
||
</div>
|
||
<p>Wrap an optional error callback with a fallback error event.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-keyword">var</span> wrapError = <span class="hljs-keyword">function</span>(<span class="hljs-params">model, options</span>) {
|
||
<span class="hljs-keyword">var</span> error = options.<span class="hljs-property">error</span>;
|
||
options.<span class="hljs-property">error</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">resp</span>) {
|
||
<span class="hljs-keyword">if</span> (error) error.<span class="hljs-title function_">call</span>(options.<span class="hljs-property">context</span>, model, resp, options);
|
||
model.<span class="hljs-title function_">trigger</span>(<span class="hljs-string">'error'</span>, model, resp, options);
|
||
};
|
||
};</pre></div></div>
|
||
|
||
</li>
|
||
|
||
|
||
<li id="section-285">
|
||
<div class="annotation">
|
||
|
||
<div class="sswrap ">
|
||
<a class="ss" href="#section-285">§</a>
|
||
</div>
|
||
<p>Provide useful information when things go wrong. This method is not meant
|
||
to be used directly; it merely provides the necessary introspection for the
|
||
external <code>debugInfo</code> function.</p>
|
||
|
||
</div>
|
||
|
||
<div class="content"><div class='highlight'><pre> <span class="hljs-title class_">Backbone</span>.<span class="hljs-property">_debug</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {
|
||
<span class="hljs-keyword">return</span> {<span class="hljs-attr">root</span>: root, <span class="hljs-attr">_</span>: _};
|
||
};
|
||
|
||
<span class="hljs-keyword">return</span> <span class="hljs-title class_">Backbone</span>;
|
||
});</pre></div></div>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
</body>
|
||
</html>
|