~ubuntu-branches/ubuntu/raring/maas/raring-updates

« back to all changes in this revision

Viewing changes to src/maasserver/static/jslibs/yui/3.4.1/docs/model-list/index.html

  • Committer: Package Import Robot
  • Author(s): Andres Rodriguez
  • Date: 2012-07-03 17:42:37 UTC
  • mfrom: (1.1.13)
  • Revision ID: package-import@ubuntu.com-20120703174237-p8l0keuuznfg721k
Tags: 0.1+bzr709+dfsg-0ubuntu1
* New Upstream release
* debian/control:
  - Depends on python-celery, python-tempita, libjs-yui3-{full,min},
    libjs-raphael
* debian/maas.install:
  - Install apiclient, celeryconfig.py, maas-import-pxe-files, preseeds_v2.
  - Update to install various files from chroot, rather tha manually copy
    them from the source.
* debian/maas.links: symlink celeryconfig.py
* debian/maas.maas-celery.upstart: Add job.
* debian/rules:
  - Install celery upstart job.
  - Do not install jslibs as packages are now used.
  - Drop copying of maas_local_settings_sample.py as source now ships
    a maas_local_settings.py
* debian/patches:
  - 04-maas-http-fix.patch: Drop. Merged upstream.
  - 01-fix-database-settings.patch: Refreshed.
  - 99_enums_js.patch: Added until creation of enum.js / build process
    is fixed.
* debian/maas.postinst: Update bzr version to correctly handle upgrades.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<!DOCTYPE html>
2
 
<html lang="en">
3
 
<head>
4
 
    <meta charset="utf-8">
5
 
    <title>Model List</title>
6
 
    <link rel="stylesheet" href="http://yui.yahooapis.com/3.4.0pr3/build/cssgrids/grids-min.css">
7
 
    <link rel="stylesheet" href="../assets/css/main.css">
8
 
    <link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
9
 
    <script src="../../build/yui/yui-min.js"></script>
10
 
</head>
11
 
<body>
12
 
 
13
 
<div id="doc">
14
 
    <h1>Model List</h1>
15
 
 
16
 
    
17
 
        <a href="#toc" class="jump">Jump to Table of Contents</a>
18
 
    
19
 
 
20
 
    <div class="yui3-g">
21
 
        <div id="main" class="yui3-u">
22
 
            <div class="content"><div class="intro">
23
 
<p>
24
 
A Model List is an array-like ordered list of <a href="../model/index.html">Model</a> instances with methods for adding, removing, sorting, filtering, and performing other actions on models in the list.
25
 
</p>
26
 
 
27
 
<p>
28
 
A Model instance may exist in zero or more lists. All events fired by a model automatically bubble up to all the lists that contain that model, so lists serve as convenient aggregators for model events.
29
 
</p>
30
 
 
31
 
<p>
32
 
<code>Y.ModelList</code> also exposes a sync API similar to the one used by <code>Y.Model</code>, making it easy to implement syncing logic to load lists of models from a persistence layer or remote server.
33
 
</p>
34
 
</div>
35
 
 
36
 
<h2 id="getting-started">Getting Started</h2>
37
 
 
38
 
<p>
39
 
To include the source files for Model List and its dependencies, first load
40
 
the YUI seed file if you haven't already loaded it.
41
 
</p>
42
 
 
43
 
<pre class="code prettyprint">&lt;script src=&quot;http:&#x2F;&#x2F;yui.yahooapis.com&#x2F;3.4.1&#x2F;build&#x2F;yui&#x2F;yui-min.js&quot;&gt;&lt;&#x2F;script&gt;</pre>
44
 
 
45
 
 
46
 
<p>
47
 
Next, create a new YUI instance for your application and populate it with the
48
 
modules you need by specifying them as arguments to the <code>YUI().use()</code> method.
49
 
YUI will automatically load any dependencies required by the modules you
50
 
specify.
51
 
</p>
52
 
 
53
 
<pre class="code prettyprint">&#x2F;&#x2F; Create a new YUI instance and populate it with the required modules.
54
 
YUI().use(&#x27;model-list&#x27;, function (Y) {
55
 
    &#x2F;&#x2F; Model List is available and ready for use. Add implementation
56
 
    &#x2F;&#x2F; code here.
57
 
});</pre>
58
 
 
59
 
 
60
 
<p>
61
 
For more information on creating YUI instances and on the
62
 
<a href="http://yuilibrary.com/yui/docs/api/classes/YUI.html#method_use"><code>use()</code> method</a>, see the
63
 
documentation for the <a href="../yui/index.html">YUI Global object</a>.
64
 
</p>
65
 
 
66
 
 
67
 
<h2 id="using-model-list">Using Model List</h2>
68
 
 
69
 
<h3 id="instantiating-a-model-list">Instantiating a Model List</h3>
70
 
 
71
 
<p>
72
 
Most of the classes in the App Framework are meant to be extended, but if your needs are simple and you don't plan to implement a custom sort comparator or sync layer for your lists, you can probably just instantiate <code>Y.ModelList</code> directly.
73
 
</p>
74
 
 
75
 
<pre class="code prettyprint">&#x2F;&#x2F; Instantiate a new list that will contain instances of the Y.PieModel model
76
 
&#x2F;&#x2F; class.
77
 
var list = new Y.ModelList({model: Y.PieModel});</pre>
78
 
 
79
 
 
80
 
<p>
81
 
The <code>model</code> config parameter configures the list to contain models that are instances of the <code>Y.PieModel</code> class (which you can read more about in the <a href="../model/index.html">Model User Guide</a>).
82
 
</p>
83
 
 
84
 
<p>
85
 
You're not strictly required to provide a <code>model</code> class, but doing so will allow you to pass plain hashes of attributes to the list's <code>add()</code> and <code>create()</code> methods and have them automatically turned into model instances. If you don't specify a <code>model</code> class, you'll need to pass existing model instances to these methods.
86
 
</p>
87
 
 
88
 
<h3 id="extending-ymodellist">Extending <code>Y.ModelList</code></h3>
89
 
 
90
 
<p>
91
 
Extending the <code>Y.ModelList</code> class allows you to create a custom class in which you may provide a custom sort comparator function, sync layer, or other logic specific to your lists. This is optional, but is a great way to add custom functionality to a model list in an efficient and maintainable way.
92
 
</p>
93
 
 
94
 
<p>
95
 
In this example, we'll create a <code>Y.PieList</code> class. Each instance of this class will contain <code>Y.PieModel</code> instances representing delicious pies.
96
 
</p>
97
 
 
98
 
<pre class="code prettyprint">Y.PieList = Y.Base.create(&#x27;pieList&#x27;, Y.ModelList, [], {
99
 
  &#x2F;&#x2F; Add prototype properties and methods for your List here if desired. These
100
 
  &#x2F;&#x2F; will be available to all instances of your List.
101
 
 
102
 
  &#x2F;&#x2F; Specifies that this list is meant to contain instances of Y.PieModel.
103
 
  model: Y.PieModel,
104
 
 
105
 
  &#x2F;&#x2F; Returns an array of PieModel instances that have been eaten.
106
 
  eaten: function () {
107
 
    return Y.Array.filter(this.toArray(), function (model) {
108
 
      return model.get(&#x27;slices&#x27;) === 0;
109
 
    });
110
 
  },
111
 
 
112
 
  &#x2F;&#x2F; Returns the total number of pie slices remaining among all the pies in
113
 
  &#x2F;&#x2F; the list.
114
 
  totalSlices: function () {
115
 
    var slices = 0;
116
 
 
117
 
    this.each(function (model) {
118
 
      slices += model.get(&#x27;slices&#x27;);
119
 
    });
120
 
 
121
 
    return slices;
122
 
  }
123
 
});</pre>
124
 
 
125
 
 
126
 
<p>
127
 
You can now create instances of <code>Y.PieList</code>.
128
 
</p>
129
 
 
130
 
<pre class="code prettyprint">var pies = new Y.PieList();</pre>
131
 
 
132
 
 
133
 
<h3 id="adding-removing-and-retrieving-models">Adding, Removing, and Retrieving Models</h3>
134
 
 
135
 
<h4 id="adding-models">Adding Models</h4>
136
 
 
137
 
<p>
138
 
Use the <a href="http://yuilibrary.com/yui/docs/api/classes/ModelList.html#method_add"><code>add()</code></a>, <a href="http://yuilibrary.com/yui/docs/api/classes/ModelList.html#method_create"><code>create()</code></a>, and <a href="http://yuilibrary.com/yui/docs/api/classes/ModelList.html#method_reset"><code>reset()</code></a> methods to put models into a list.
139
 
</p>
140
 
 
141
 
<p>
142
 
The difference between <code>add()</code> and <code>create()</code> is that <code>add()</code> simply adds one or more models to the list, while <code>create()</code> first saves a model and only adds it to the list once the model's sync layer indicates that the save operation was successful.
143
 
</p>
144
 
 
145
 
<pre class="code prettyprint">&#x2F;&#x2F; Add a single model to the list.
146
 
pies.add(new Y.PieModel({type: &#x27;pecan&#x27;}));
147
 
 
148
 
&#x2F;&#x2F; Add multiple models to the list.
149
 
pies.add([
150
 
  new Y.PieModel({type: &#x27;apple&#x27;}),
151
 
  new Y.PieModel({type: &#x27;maple custard&#x27;})
152
 
]);
153
 
 
154
 
&#x2F;&#x2F; Save a model, then add it to the list.
155
 
pies.create(new Y.PieModel({type: &#x27;pumpkin&#x27;}));</pre>
156
 
 
157
 
 
158
 
<p>
159
 
If your list's <code>model</code> property is set to a model class, then you can just pass attribute hashes to the <code>add()</code> and <code>create()</code> methods, and the list will automatically create new model instances for you.
160
 
</p>
161
 
 
162
 
<pre class="code prettyprint">&#x2F;&#x2F; Add a single model to the list.
163
 
pies.add({type: &#x27;pecan&#x27;});
164
 
 
165
 
&#x2F;&#x2F; Add multiple models to the list.
166
 
pies.add([
167
 
  {type: &#x27;apple&#x27;},
168
 
  {type: &#x27;maple custard&#x27;}
169
 
]);
170
 
 
171
 
&#x2F;&#x2F; Save a model, then add it to the list.
172
 
pies.create({type: &#x27;pumpkin&#x27;});</pre>
173
 
 
174
 
 
175
 
<p>
176
 
The <code>create()</code> method accepts an optional callback function, which will be executed when the save operation finishes. Provide a callback if you'd like to be notified of the success or failure of the save operation.
177
 
</p>
178
 
 
179
 
<pre class="code prettyprint">pies.create({type: &#x27;watermelon chiffon&#x27;}, function (err) {
180
 
  if (!err) {
181
 
    &#x2F;&#x2F; The save operation was successful!
182
 
  }
183
 
});</pre>
184
 
 
185
 
 
186
 
<p>
187
 
The <code>reset()</code> method removes any models that are already in the list and then adds the models you specify. Instead of generating many <code>add</code> and <code>remove</code> events, the <code>reset()</code> method only generates a single <code>reset</code> event. Use <code>reset()</code> when you need to repopulate the entire list efficiently.
188
 
</p>
189
 
 
190
 
<pre class="code prettyprint">&#x2F;&#x2F; Remove all existing models from the list and add new ones.
191
 
pies.reset([
192
 
  {type: &#x27;lemon meringue&#x27;},
193
 
  {type: &#x27;banana cream&#x27;}
194
 
]);</pre>
195
 
 
196
 
 
197
 
<p>
198
 
You can also call <code>reset()</code> with no arguments to quickly empty the list.
199
 
</p>
200
 
 
201
 
<pre class="code prettyprint">&#x2F;&#x2F; Empty the list.
202
 
pies.reset();</pre>
203
 
 
204
 
 
205
 
<p>
206
 
Models are automatically inserted into the list at the correct index based on the current sort comparator, so the list is always guaranteed to be sorted. By default, no sort comparator is defined, so models are sorted in insertion order. See <a href="#creating-a-custom-sort-comparator">Creating a Custom Sort Comparator</a> for details on customizing how a list is sorted.
207
 
</p>
208
 
 
209
 
<h4 id="retrieving-models">Retrieving Models</h4>
210
 
 
211
 
<p>
212
 
Models in the list can be retrieved by their <code>id</code> attribute, their <code>clientId</code> attribute, or by their numeric index within the list.
213
 
</p>
214
 
 
215
 
<pre class="code prettyprint">&#x2F;&#x2F; Look up a model by its id.
216
 
pies.getById(&#x27;1234&#x27;);
217
 
 
218
 
&#x2F;&#x2F; Look up a model by its clientId.
219
 
pies.getByClientId(&#x27;pie_42&#x27;);
220
 
 
221
 
&#x2F;&#x2F; Look up a model by its numeric index within the list.
222
 
pies.item(0);
223
 
 
224
 
&#x2F;&#x2F; Find the index of a model instance within the list.
225
 
pies.indexOf(pies.getById(&#x27;1234&#x27;));</pre>
226
 
 
227
 
 
228
 
<h4 id="removing-models">Removing Models</h4>
229
 
 
230
 
<p>
231
 
Pass a model or array of models to the <a href="http://yuilibrary.com/yui/docs/api/classes/ModelList.html#method_remove"><code>remove()</code></a> method to remove them from the list.
232
 
</p>
233
 
 
234
 
<pre class="code prettyprint">&#x2F;&#x2F; Remove a single model from the list.
235
 
pies.remove(pies.getById(&#x27;1234&#x27;));
236
 
 
237
 
&#x2F;&#x2F; Remove multiple models from the list.
238
 
pies.remove([
239
 
  pies.getById(&#x27;1235&#x27;),
240
 
  pies.getById(&#x27;1236&#x27;)
241
 
]);</pre>
242
 
 
243
 
 
244
 
<p>
245
 
This will only remove the specified model instances from the list; it won't actually call the models' <a href="http://yuilibrary.com/yui/docs/api/classes/Model.html#method_destroy"><code>destroy()</code></a> methods or delete them via the models' sync layer. Calling a model's <code>destroy()</code> method will automatically remove it from any lists it's in, so that would be a better option if you want to both remove and destroy or delete a model.
246
 
</p>
247
 
 
248
 
<h3 id="list-attributes">List Attributes</h3>
249
 
 
250
 
<p>
251
 
Model Lists themselves don't provide any attributes, but calling the <a href="http://yuilibrary.com/yui/docs/api/classes/ModelList.html#method_get"><code>get()</code></a>, <a href="http://yuilibrary.com/yui/docs/api/classes/ModelList.html#method_getAsHTML"><code>getAsHTML()</code></a>, or <a href="http://yuilibrary.com/yui/docs/api/classes/ModelList.html#method_getAsURL"><code>getAsURL()</code></a> methods on the list will return an array containing the specified attribute values from every model in the list.
252
 
</p>
253
 
 
254
 
<pre class="code prettyprint">pies.add([
255
 
  {type: &#x27;pecan&#x27;},
256
 
  {type: &#x27;strawberries &amp; cream&#x27;},
257
 
  {type: &#x27;blueberry&#x27;}
258
 
]);
259
 
 
260
 
pies.get(&#x27;type&#x27;);
261
 
&#x2F;&#x2F; =&gt; [&quot;pecan&quot;, &quot;strawberries &amp; cream&quot;, &quot;blueberry&quot;]
262
 
 
263
 
pies.getAsHTML(&#x27;type&#x27;);
264
 
&#x2F;&#x2F; =&gt; [&quot;pecan&quot;, &quot;strawberries &amp;amp; cream&quot;, &quot;blueberry&quot;]
265
 
 
266
 
pies.getAsURL(&#x27;type&#x27;);
267
 
&#x2F;&#x2F; =&gt; [&quot;pecan&quot;, &quot;strawberries%20%26%20cream&quot;, &quot;blueberry&quot;]</pre>
268
 
 
269
 
 
270
 
<h3 id="list-events">List Events</h3>
271
 
 
272
 
<p>
273
 
Model List instances provide the following events:
274
 
</p>
275
 
 
276
 
<table>
277
 
  <thead>
278
 
    <tr>
279
 
      <th>Event</th>
280
 
      <th>When</th>
281
 
      <th>Payload</th>
282
 
    </tr>
283
 
  </thead>
284
 
  <tbody>
285
 
    <tr>
286
 
      <td><code>add</code></td>
287
 
      <td>A model is added to the list.</td>
288
 
      <td>
289
 
        <dl>
290
 
          <dt><code>model</code> (<em>Y.Model</em>)</dt>
291
 
          <dd>
292
 
            The model instance being added.
293
 
          </dd>
294
 
 
295
 
          <dt><code>index</code> (<em>Number</em>)</dt>
296
 
          <dd>
297
 
            The index at which the model will be added.
298
 
          </dd>
299
 
        </dl>
300
 
      </td>
301
 
    </tr>
302
 
 
303
 
    <tr>
304
 
      <td><code>error</code></td>
305
 
      <td>An error occurs, such as when an attempt is made to add a duplicate model to the list, or when a sync layer response can't be parsed.</td>
306
 
      <td>
307
 
        <dl>
308
 
          <dt><code>error</code> (<em>Any</em>)</dt>
309
 
          <dd>
310
 
            Error message, object, or exception generated by the error. Calling <code>toString()</code> on this should result in a meaningful error message.
311
 
          </dd>
312
 
 
313
 
          <dt><code>src</code> (<em>String</em>)</dt>
314
 
          <dd>
315
 
            <p>
316
 
            Source of the error. May be one of the following (or any custom error source defined by a ModelList subclass):
317
 
            </p>
318
 
 
319
 
            <dl>
320
 
              <dt><code>add</code></dt>
321
 
              <dd>
322
 
                Error while adding a model (probably because it's already in the list and can't be added again). The model in question will be provided as the <code>model</code> property on the event facade.
323
 
              </dd>
324
 
 
325
 
              <dt><code>parse</code></dt>
326
 
              <dd>
327
 
                An error parsing a JSON response. The response in question will be provided as the <code>response</code> property on the event facade.
328
 
              </dd>
329
 
 
330
 
              <dt><code>remove</code></dt>
331
 
              <dd>
332
 
                Error while removing a model (probably because it isn't in the list and can't be removed). The model in question will be provided as the <code>model</code> property on the event facade.
333
 
              </dd>
334
 
            </dl>
335
 
        </dl>
336
 
      </td>
337
 
    </tr>
338
 
 
339
 
    <tr>
340
 
      <td><code>remove</code></td>
341
 
      <td>A model is removed from the list.</td>
342
 
      <td>
343
 
        <dl>
344
 
          <dt><code>model</code> (<em>Y.Model</em>)</dt>
345
 
          <dd>
346
 
            The model instance being removed.
347
 
          </dd>
348
 
 
349
 
          <dt><code>index</code> (<em>Number</em>)</dt>
350
 
          <dd>
351
 
            The index of the model being removed.
352
 
          </dd>
353
 
        </dl>
354
 
      </td>
355
 
    </tr>
356
 
 
357
 
    <tr>
358
 
      <td><code>reset</code></td>
359
 
      <td>The list is completely reset or sorted.</td>
360
 
      <td>
361
 
        <dl>
362
 
          <dt><code>models</code> (<em>Array</em>)</dt>
363
 
          <dd>
364
 
            Array of the list's new models after the reset.
365
 
          </dd>
366
 
 
367
 
          <dt><code>src</code> (<em>String</em>)</dt>
368
 
          <dd>
369
 
            Source of the event. May be either "reset" or "sort".
370
 
          </dd>
371
 
        </dl>
372
 
      </td>
373
 
    </tr>
374
 
  </tbody>
375
 
</table>
376
 
 
377
 
<p>
378
 
Each of these events is preventable, which means you can subscribe to the "on" phase of an event and call <code>e.preventDefault()</code> in your subscriber function to prevent the event from actually occurring. This works because "on" subscribers actually run before an event causes any default logic to run.
379
 
</p>
380
 
 
381
 
<p>
382
 
For example, you could prevent a model from being added to the list like this:
383
 
</p>
384
 
 
385
 
<pre class="code prettyprint">pies.on(&#x27;add&#x27;, function (e) {
386
 
  if (e.model.get(&#x27;type&#x27;) === &#x27;rhubarb&#x27;) {
387
 
    &#x2F;&#x2F; Eww. No rhubarb for me please.
388
 
    e.preventDefault();
389
 
  }
390
 
});</pre>
391
 
 
392
 
 
393
 
<p>
394
 
If you only want to be notified <em>after</em> an event occurs, and only when that event wasn't prevented, subscribe to the "after" phase.
395
 
</p>
396
 
 
397
 
<pre class="code prettyprint">pies.after(&#x27;add&#x27;, function (e) {
398
 
  &#x2F;&#x2F; Only runs after a model is successfully added to the list.
399
 
});</pre>
400
 
 
401
 
 
402
 
<h4 id="subscribing-to-bubbled-model-events">Subscribing to Bubbled Model Events</h4>
403
 
 
404
 
<p>
405
 
A model's events bubble up to any model lists it belongs to. This means, for example, that you can subscribe to the <code>*:change</code> event on the list to be notified whenever the <code>change</code> event of any model in the list is fired.
406
 
</p>
407
 
 
408
 
<pre class="code prettyprint">&#x2F;&#x2F; Subscribe to change events from all models in the &#x60;pies&#x60; model list.
409
 
pies.on(&#x27;*:change&#x27;, function (e) {
410
 
  &#x2F;&#x2F; e.target is a reference to the model instance that caused the event.
411
 
  var model  = e.target,
412
 
      slices = e.changed.slices;
413
 
 
414
 
  if (slices &amp;&amp; slices.newVal &lt; slices.prevVal) {
415
 
    Y.log(&#x27;Somebody just ate a slice of &#x27; + model.get(&#x27;type&#x27;) + &#x27; pie!&#x27;);
416
 
  }
417
 
});</pre>
418
 
 
419
 
 
420
 
<p>
421
 
If a model exists in more than one list, its events will bubble up to all the lists it's in.
422
 
</p>
423
 
 
424
 
<h3 id="manipulating-the-list">Manipulating the List</h3>
425
 
 
426
 
<p>
427
 
Model Lists extend <code>Y.ArrayList</code>, which means they provide many convenient array-like methods for manipulating the list of models.
428
 
</p>
429
 
 
430
 
<p>
431
 
For example, you can use <code>each()</code> and <code>some()</code> to iterate over the list, <code>size()</code> to get the number of models in the list, and <code>map()</code> to pass each model in the list to a function and return an array of that function's return values.
432
 
</p>
433
 
 
434
 
<p>
435
 
For more details, see the <a href="http://yuilibrary.com/yui/docs/api/classes/ModelList.html">Model List API docs</a>.
436
 
</p>
437
 
 
438
 
<h2 id="creating-a-custom-sort-comparator">Creating a Custom Sort Comparator</h2>
439
 
 
440
 
<p>
441
 
When a model is added to a list, it's automatically inserted at the correct index to maintain the sort order of the list. This sort order is determined by the return value of the list's optional <code>comparator()</code> function.
442
 
</p>
443
 
 
444
 
<p>
445
 
By default, lists don't have a comparator function, so models are sorted in the order they're added. To customize how models are sorted, override your list's <code>comparator()</code> function with a function that accepts a single model instance as an argument and returns a value that should be compared with return values from other models to determine the sort order.
446
 
</p>
447
 
 
448
 
<pre class="code prettyprint">Y.PieList = Y.Base.create(&#x27;pieList&#x27;, Y.ModelList, [], {
449
 
  &#x2F;&#x2F; ... prototype methods and properties ...
450
 
 
451
 
  &#x2F;&#x2F; Custom comparator to keep pies sorted by type.
452
 
  comparator: function (model) {
453
 
    return model.get(&#x27;type&#x27;);
454
 
  }
455
 
});</pre>
456
 
 
457
 
 
458
 
<p>
459
 
If you change the comparator function after models have already been added to the list, you can call the list's <code>sort()</code> function to re-sort the entire list.
460
 
</p>
461
 
 
462
 
<pre class="code prettyprint">&#x2F;&#x2F; Change the comparator of a pie list and re-sort it after adding some pies.
463
 
var pies = new Y.PieList();
464
 
 
465
 
pies.add([
466
 
  {type: &#x27;chocolate cream&#x27;, slices: 8},
467
 
  {type: &#x27;dutch apple&#x27;, slices: 6}
468
 
]);
469
 
 
470
 
pies.get(&#x27;type&#x27;);
471
 
&#x2F;&#x2F; =&gt; [&#x27;chocolate cream&#x27;, &#x27;dutch apple&#x27;]
472
 
 
473
 
pies.comparator = function (model) {
474
 
  return model.get(&#x27;slices&#x27;);
475
 
};
476
 
 
477
 
pies.sort();
478
 
 
479
 
pies.get(&#x27;type&#x27;);
480
 
&#x2F;&#x2F; =&gt; [&#x27;dutch apple&#x27;, &#x27;chocolate cream&#x27;]</pre>
481
 
 
482
 
 
483
 
<p>
484
 
Behind the scenes, ModelList passes each model to the <code>comparator()</code> method and then performs a simple natural order comparison on the return values to determine whether a given model should be sorted above, below, or at the same position as another model. The logic looks like this:
485
 
</p>
486
 
 
487
 
<pre class="code prettyprint">&#x2F;&#x2F; &#x60;a&#x60; and &#x60;b&#x60; are both Model instances.
488
 
function (a, b) {
489
 
  &#x2F;&#x2F; &#x60;this&#x60; is the current ModelList instance.
490
 
  var aValue = this.comparator(a),
491
 
      bValue = this.comparator(b);
492
 
 
493
 
  return aValue &lt; bValue ? -1 : (aValue &gt; bValue ? 1 : 0);
494
 
}</pre>
495
 
 
496
 
 
497
 
<p>
498
 
If necessary, you can override ModelList's protected <code>_sync()</code> method (note the underscore prefix) to further customize this sorting logic.
499
 
</p>
500
 
 
501
 
<h2 id="implementing-a-list-sync-layer">Implementing a List Sync Layer</h2>
502
 
 
503
 
<p>
504
 
A list's <a href="http://yuilibrary.com/yui/docs/api/classes/ModelList.html#method_load"><code>load()</code></a> method internally calls the list's <a href="http://yuilibrary.com/yui/docs/api/classes/ModelList.html#method_sync"><code>sync()</code></a> method to carry out the load action. The default <code>sync()</code> method doesn't actually do anything, but by overriding the <code>sync()</code> method, you can provide a custom sync layer.
505
 
</p>
506
 
 
507
 
<p>
508
 
A sync layer might make Ajax requests to a remote server, or it might act as a wrapper around local storage, or any number of other things.
509
 
</p>
510
 
 
511
 
<p>
512
 
A Model List sync layer works exactly the same way as a <a href="../model/index.html">Model</a> sync layer, except that only the <code>read</code> action is currently supported.
513
 
</p>
514
 
 
515
 
<h3 id="the-sync-method">The <code>sync()</code> Method</h3>
516
 
 
517
 
<p>
518
 
When the <code>sync()</code> method is called, it receives three arguments:
519
 
</p>
520
 
 
521
 
<dl>
522
 
  <dt><strong><code>action</code> (<em>String</em>)</strong></dt>
523
 
  <dd>
524
 
    <p>
525
 
    A string that indicates the intended sync action. May be one of the following values:
526
 
    </p>
527
 
 
528
 
    <dl>
529
 
      <dt><strong><code>read</code></strong></dt>
530
 
      <dd>
531
 
        <p>
532
 
        Read an existing list of models.
533
 
        </p>
534
 
      </dd>
535
 
 
536
 
      <dd><em>Other values are not currently supported, but may be added in a future release.</em></dd>
537
 
    </dl>
538
 
  </dd>
539
 
 
540
 
  <dt><strong><code>options</code> (<em>Object</em>)</strong></dt>
541
 
  <dd>
542
 
    <p>
543
 
    A hash containing any options that were passed to the <code>load()</code> method. This may be used to pass custom options to a sync layer.
544
 
    </p>
545
 
  </dd>
546
 
 
547
 
  <dt><strong><code>callback</code> (<em>Function</em>)</strong></dt>
548
 
  <dd>
549
 
    <p>
550
 
    A callback function that should be called when the sync operation is complete. The callback expects to receive the following arguments:
551
 
    </p>
552
 
 
553
 
    <dl>
554
 
      <dt><strong><code>err</code></strong></dt>
555
 
      <dd>
556
 
        <p>
557
 
        Error message or object if an error occured, <code>null</code> or <code>undefined</code> if the operation was successful.
558
 
        </p>
559
 
      </dd>
560
 
 
561
 
      <dt><strong><code>response</code></strong></dt>
562
 
      <dd>
563
 
        <p>
564
 
        Response from the persistence layer, if any. This will be passed to the <code>parse()</code> method to be parsed.
565
 
        </p>
566
 
      </dd>
567
 
    </dl>
568
 
  </dd>
569
 
</dl>
570
 
 
571
 
<p>
572
 
Implementing a sync layer is as simple as handling the requested sync action and then calling the callback function. Here's a sample sync layer that loads a list of models from local storage:
573
 
</p>
574
 
 
575
 
<pre class="code prettyprint">Y.PieList = Y.Base.create(&#x27;pieList&#x27;, Y.ModelList, [], {
576
 
  &#x2F;&#x2F; ... prototype methods and properties ...
577
 
 
578
 
  &#x2F;&#x2F; Custom sync layer.
579
 
  sync: function (action, options, callback) {
580
 
    var data;
581
 
 
582
 
    if (action === &#x27;read&#x27;) {
583
 
      data = localStorage.getItem(&#x27;pies&#x27;) || [];
584
 
      callback(null, data);
585
 
    } else {
586
 
      callback(&#x27;Unsupported sync action: &#x27; + action);
587
 
    }
588
 
  }
589
 
});</pre>
590
 
 
591
 
 
592
 
<h3 id="the-parse-method">The <code>parse()</code> Method</h3>
593
 
 
594
 
<p>
595
 
Depending on the kind of response your sync layer returns, you may need to override the <a href="http://yuilibrary.com/yui/docs/api/classes/ModelList.html#method_parse"><code>parse()</code></a> method as well. The default <code>parse()</code> implementation can parse either a JavaScript array of model hashes or a JSON string that represents a JavaScript array of model hashes. If your response data is in another format, such as a nested JSON object or XML, override the <code>parse()</code> method to provide a custom parser implementation.
596
 
</p>
597
 
 
598
 
<p>
599
 
If an error occurs while parsing a response, fire an <code>error</code> event with <code>type</code> "parse".
600
 
</p>
601
 
 
602
 
<p>
603
 
This sample demonstrates a custom parser for responses in which the list data is contained in a <code>data</code> property of the response object.
604
 
</p>
605
 
 
606
 
<pre class="code prettyprint">&#x2F;&#x2F; Custom response parser.
607
 
parse: function (response) {
608
 
  if (response.data) {
609
 
    return response.data;
610
 
  }
611
 
 
612
 
  this.fire(&#x27;error&#x27;, {
613
 
    type : &#x27;parse&#x27;,
614
 
    error: &#x27;No data in the response.&#x27;
615
 
  });
616
 
}</pre>
617
 
 
618
 
</div>
619
 
        </div>
620
 
 
621
 
        <div id="sidebar" class="yui3-u">
622
 
            
623
 
                <div id="toc" class="sidebox">
624
 
                    <div class="hd">
625
 
                        <h2 class="no-toc">Table of Contents</h2>
626
 
                    </div>
627
 
 
628
 
                    <div class="bd">
629
 
                        <ul class="toc">
630
 
<li>
631
 
<a href="#getting-started">Getting Started</a>
632
 
</li>
633
 
<li>
634
 
<a href="#using-model-list">Using Model List</a>
635
 
<ul class="toc">
636
 
<li>
637
 
<a href="#instantiating-a-model-list">Instantiating a Model List</a>
638
 
</li>
639
 
<li>
640
 
<a href="#extending-ymodellist">Extending <code>Y.ModelList</code></a>
641
 
</li>
642
 
<li>
643
 
<a href="#adding-removing-and-retrieving-models">Adding, Removing, and Retrieving Models</a>
644
 
<ul class="toc">
645
 
<li>
646
 
<a href="#adding-models">Adding Models</a>
647
 
</li>
648
 
<li>
649
 
<a href="#retrieving-models">Retrieving Models</a>
650
 
</li>
651
 
<li>
652
 
<a href="#removing-models">Removing Models</a>
653
 
</li>
654
 
</ul>
655
 
</li>
656
 
<li>
657
 
<a href="#list-attributes">List Attributes</a>
658
 
</li>
659
 
<li>
660
 
<a href="#list-events">List Events</a>
661
 
<ul class="toc">
662
 
<li>
663
 
<a href="#subscribing-to-bubbled-model-events">Subscribing to Bubbled Model Events</a>
664
 
</li>
665
 
</ul>
666
 
</li>
667
 
<li>
668
 
<a href="#manipulating-the-list">Manipulating the List</a>
669
 
</li>
670
 
</ul>
671
 
</li>
672
 
<li>
673
 
<a href="#creating-a-custom-sort-comparator">Creating a Custom Sort Comparator</a>
674
 
</li>
675
 
<li>
676
 
<a href="#implementing-a-list-sync-layer">Implementing a List Sync Layer</a>
677
 
<ul class="toc">
678
 
<li>
679
 
<a href="#the-sync-method">The <code>sync()</code> Method</a>
680
 
</li>
681
 
<li>
682
 
<a href="#the-parse-method">The <code>parse()</code> Method</a>
683
 
</li>
684
 
</ul>
685
 
</li>
686
 
</ul>
687
 
                    </div>
688
 
                </div>
689
 
            
690
 
 
691
 
            
692
 
 
693
 
            
694
 
                <div class="sidebox">
695
 
                    <div class="hd">
696
 
                        <h2 class="no-toc">Examples That Use This Component</h2>
697
 
                    </div>
698
 
 
699
 
                    <div class="bd">
700
 
                        <ul class="examples">
701
 
                            
702
 
                                
703
 
                                    <li data-description="A basic todo list built with the Model, Model List, and View components.">
704
 
                                        <a href="../app/app-todo.html">Todo List</a>
705
 
                                    </li>
706
 
                                
707
 
                            
708
 
                        </ul>
709
 
                    </div>
710
 
                </div>
711
 
            
712
 
        </div>
713
 
    </div>
714
 
</div>
715
 
 
716
 
<script src="../assets/vendor/prettify/prettify-min.js"></script>
717
 
<script>prettyPrint();</script>
718
 
 
719
 
</body>
720
 
</html>