Skip to content

Commit 473a3fd

Browse files
author
Vlad Balin
committed
docs update
1 parent a2f3147 commit 473a3fd

File tree

3 files changed

+225
-69
lines changed

3 files changed

+225
-69
lines changed

docs/chapters/collection.md

Lines changed: 111 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,39 @@ Specify the record type inside of the collection's definition. This property is
4949
}
5050
```
5151

52+
### `static` comparator = 'attrName'
53+
54+
Maintain the collection in sorted order by the given record's attribute.
55+
56+
### `static` comparator = x => number | string
57+
58+
"sortBy" comparator functions take a record and return a numeric or string value by which the record should be ordered relative to others.
59+
60+
### `static` comparator = ( x, y ) => -1 | 0 | 1
61+
62+
"sort" comparator functions take two records, and return -1 if the first record should come before the second, 0 if they are of the same rank and 1 if the first record should come after.
63+
64+
Note how even though all of the chapters in this example are added backwards, they come out in the proper order:
65+
66+
```javascript
67+
@define class Chapter extends Record {
68+
static attributes = {
69+
page : Number,
70+
title : String
71+
}
72+
}
73+
74+
var chapters = new Chapter.Collection();
75+
76+
chapters.comparator = 'page';
77+
78+
chapters.add(new Chapter({page: 9, title: "The End"}));
79+
chapters.add(new Chapter({page: 5, title: "The Middle"}));
80+
chapters.add(new Chapter({page: 1, title: "The Beginning"}));
81+
82+
alert(chapters.map( x => x.title ));
83+
```
84+
5285
## Create and dispose
5386

5487
### new Collection( records?, options? )
@@ -231,6 +264,10 @@ Any additional changes made to the collection or its items in event handlers wil
231264

232265
Similar to the `collection.each`, but wraps an iteration in a transaction. The single `changes` event will be emitted for the group of changes to the records made in `updateEach`.
233266

267+
### collection.sort( options? )
268+
269+
Force a collection to re-sort itself. You don't need to call this under normal circumstances, as a collection with a comparator will sort itself whenever a record is added. To disable sorting when adding a record, pass `{sort: false}` to add. Calling sort triggers a "sort" event on the collection.
270+
234271
### collection.push( record, options? )
235272

236273
Add a record at the end of a collection. Takes the same options as add.
@@ -247,17 +284,9 @@ Remove and return the first record from a collection. Takes the same options as
247284

248285
## Change events
249286

250-
Object tree formed by nested records is deeply observable by default; changes in every item trigger change events for the collection and all parent elements in sequence.
287+
All changes in the records cause change events in the collections they are contained in.
251288

252-
Collection triggers following events on change:
253-
254-
- `change` *( record, options )* for every changed record.
255-
- `add` *( record, collection, options )* for every added record.
256-
- `remove` *( record, collection, options )* for every removed record.
257-
- `update` *( collection, options )* when any records were added or removed.
258-
- `sort` *( collection, options )* when any records changed their order.
259-
- `reset` *( collection, options )* if `collection.reset()` was used to update the collection.
260-
- `changes` *( collection, options )* in case of any changes.
289+
Subset collections is an exception; they don't observe changes of its elements by default.
261290

262291
### Events mixin methods (7)
263292

@@ -297,46 +326,96 @@ When a record is removed from a collection.
297326

298327
When a record inside of the collection is changed.
299328

300-
## Sorting
329+
## Serialization
301330

302-
### `static` comparator = 'attrName'
331+
All kinds of collections except `Collection.Refs` are serializable.
303332

304-
Maintain the collection in sorted order by the given record's attribute.
333+
### collection.toJSON()
305334

306-
### `static` comparator = x => number | string
335+
Produces the JSON for the given collection:
307336

308-
"sortBy" comparator functions take a record and return a numeric or string value by which the record should be ordered relative to others.
309-
310-
### `static` comparator = ( x, y ) => -1 | 0 | 1
337+
- `[ { record json }, ... ]` - array of objects for regular aggregating collection.
338+
- `[ id1, id2, ... ]` - array of record ids for the subset collection.
311339

312-
"sort" comparator functions take two records, and return -1 if the first record should come before the second, 0 if they are of the same rank and 1 if the first record should come after.
340+
<aside class="warning">Although the direct call to <code>toJSON()</code> will produce the correct JSON for the <code>Collection.Refs</code>, it cannot be restored from JSON properly. Therefore, records attributes of the <code>Collection.Refs</code> type are not serialized by default. </aside>
313341

314-
Note how even though all of the chapters in this example are added backwards, they come out in the proper order:
342+
May be overridden in the particular record or collection class to customize the JSON representation.
315343

316344
```javascript
317-
@define class Chapter extends Record {
345+
@define class Comment extends Record {
318346
static attributes = {
319-
page : Number,
320-
title : String
347+
body : ''
321348
}
322349
}
323350

324-
var chapters = new Chapter.Collection();
325-
326-
chapters.comparator = 'page';
351+
@define class BlogPost extends Record {
352+
static attributes = {
353+
title : '',
354+
body : '',
355+
comments : Comment.Collection
356+
}
357+
}
327358

328-
chapters.add(new Chapter({page: 9, title: "The End"}));
329-
chapters.add(new Chapter({page: 5, title: "The Middle"}));
330-
chapters.add(new Chapter({page: 1, title: "The Beginning"}));
359+
const post = new BlogPost({
360+
title: "Type-R is cool!",
361+
comments : [ { body : "Agree" }]
362+
});
331363

332-
alert(chapters.map( x => x.title ));
364+
const rawJSON = post.toJSON()
365+
// { title : "Type-R is cool!", body : "", comments : [{ body : "Agree" }] }
333366
```
334367

335-
### collection.sort( options? )
368+
### `options` { parse : true }
336369

337-
Force a collection to re-sort itself. You don't need to call this under normal circumstances, as a collection with a comparator will sort itself whenever a record is added. To disable sorting when adding a record, pass `{sort: false}` to add. Calling sort triggers a "sort" event on the collection.
370+
Parse raw JSON when passed as an option to the collection's constructor or update methods.
338371

339-
## Serialization
372+
### `callback` collection.parse( json )
373+
374+
Invoked internally when `{ parse : true }` is passed. May be overridden to define custom JSON transformation. Should not be called explicitly.
340375

341376
## Validation
342377

378+
Validation happens transparently on the first access to any part of the validation API. Validation results are cached. Only the changed parts of aggregation tree will be validated again.
379+
380+
### `callback` collection.validate()
381+
382+
Override in the collection subclass to add collection-level validation. Whatever is returned from `validate()` is treated as an error message and triggers the validation error.
383+
384+
<aside class="notice">Do not call this method directly, that's not the way how validation works.</aside>
385+
386+
### collection.isValid()
387+
388+
Returns `true` if the collection is valid. Similar to `!collection.validationError`.
389+
390+
### collection.isValid( recordId )
391+
392+
Returns `true` whenever the record from the collection is valid.
393+
394+
### record.validationError
395+
396+
`null` if the collection is valid, or the detailed information on validation errors.
397+
398+
- Aggregating collection is valid whenever `collection.validate()` returns `undefined` _and_ all of its records are valid.
399+
- Non-aggregating collections are valid whenever `collection.validate()` returns `undefined`.
400+
401+
```javascript
402+
// ValidationError object shape
403+
{
404+
error : /* collection-level validation error msg as returned from collection.validate() */,
405+
406+
// Collection items validation errors
407+
nested : {
408+
// Contains nested ValidationError object for nested records...
409+
/* record.cid */ : /* record.validationError */
410+
}
411+
}
412+
```
413+
414+
### collection.getValidationError( recordId )
415+
416+
Return the validation error for the given collection's item.
417+
418+
### collection.eachValidationError( iteratee : ( error, key, recordOrCollection ) => void )
419+
420+
Recursively traverse aggregation tree errors. `key` is `null` for the record-level validation error (returned from `validate()`).
421+
`recordOrCollection` is the reference to the current object.

docs/chapters/record.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,10 @@ Initialized as `null` and serialized as `record.id`. Is not recursively cloned,
251251
252252
Changes in shared record are not detected.
253253
254-
`sourceCollection` may be the singleton collection, the function returning the collection, or the string with the dot-separated _relative object path_ to the collection. In the last case, it is resolved dynamically relative to the record's `this`.
254+
`sourceCollection` may be:
255+
- the singleton collection;
256+
- the function returning the collection;
257+
- the string with the dot-separated _relative object path_ to the collection. It is resolved dynamically relative to the record's `this`. `^` symbol in path is being translated to the `getOwner()` call.
255258
256259
```javascript
257260
@define class State extends Record {
@@ -260,8 +263,6 @@ Changes in shared record are not detected.
260263
}
261264
```
262265
263-
`^` symbol in path is being translated to the `getOwner()` call.
264-
265266
<aside class="info">It's recommended to use ~paths and stores instead of ^paths.</aside>
266267
267268
### `attrDef` : Collection.subsetOf( `sourceCollection` )
@@ -461,6 +462,16 @@ some.record.transaction( record => {
461462
462463
Manual transactions with attribute assignments are superior to `record.set()` in terms of both performance and flexibility.
463464
465+
### `attrDef` : Type.has.get( `hook` )
466+
467+
Attach get hook to the record's attribute. `hook` is the function of signature `( value, attr ) => value` which is used to transform the attribute's value _before it will be read_. Hook is executed in the context of the record.
468+
469+
### `attrDef` : Type.has.set( `hook` )
470+
471+
Attach the set hook to the record's attribute. `hook` is the function of signature `( value, attr ) => value` which is used to transform the attribute's value _before it will be assigned_. Hook is executed in the context of the record.
472+
473+
If set hook will return `undefined`, it will cancel attribute update.
474+
464475
## Change events
465476
466477
### Events mixin methods (7)

0 commit comments

Comments
 (0)