From 0b97fa7cb6a7d40b0a92b3ad976ce043fed086a5 Mon Sep 17 00:00:00 2001 From: Eirik Hoem Date: Thu, 23 May 2013 12:38:58 +0200 Subject: [PATCH 1/5] Added Backbone Relational 0.8.5 --- backbone-relational/backbone-relational.d.ts | 168 +++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 backbone-relational/backbone-relational.d.ts diff --git a/backbone-relational/backbone-relational.d.ts b/backbone-relational/backbone-relational.d.ts new file mode 100644 index 000000000..3c1b953ac --- /dev/null +++ b/backbone-relational/backbone-relational.d.ts @@ -0,0 +1,168 @@ +// Type definitions for Backbone 0.8.5 +// Project: http://backbonerelational.org/ +// Definitions by: Eirik Hoem +// Definitions: https://github.com/borisyankov/DefinitelyTyped + + +/// + +/// + +declare module Backbone { + export class RelationalModel extends Model { + static extend(properties:any, classProperties?:any):any; // do not use, prefer TypeScript's extend functionality + relations:any; + subModelTypes:any; + subModelTypeAttribute:any; + + + initializeRelations(options:any):void; + + updateRelations(options:any):void; + + queue(func:any):void; + + processQueue():void; + + getRelation(name:string):Relation; + + getRelations():Relation[]; + + fetchRelated(key:string, options?:any, update?:bool):any; + + toJSON():any; + + setup(); + + build(attributes:any, options?:any); + + findOrCreate(attributes:string, options?:any); + + findOrCreate(attributes:number, options?:any); + + findOrCreate(attributes:any, options?:any); + } + + export class Relation extends Model { + + options:any; + instance:any; + key:any; + keyContents:any; + relatedModel:any; + relatedCollection:any; + reverseRelation:any; + related:any; + + checkPreconditions():bool; + + setRelated(related:Model):void; + + setRelated(related:Collection):void; + + getReverseRelations(model:RelationalModel):Relation; + + destroy():void; + } + + export class HasOne extends Relation { + collectionType:any; + + findRelated(options:any):Model; + + setKeyContents(keyContents:string):void; + + setKeyContents(keyContents:string[]):void; + + setKeyContents(keyContents:number):void; + + setKeyContents(keyContents:number[]):void; + + setKeyContents(keyContents:Collection):void; + + onChange(model:Model, attr:any, options:any):void; + + handleAddition(model:Model, coll:Collection, options:any):void; + + handleRemoval(model:Model, coll:Collection, options:any):void; + + handleReset(coll:Collection, options:any):void; + + tryAddRelated(model:Model, coll:any, options:any):void; + + addRelated(model:Model, options:any):void; + + removeRelated(model:Model, coll:any, options:any):void; + + } + + + export class HasMany extends Relation { + collectionType:any; + + findRelated(options:any):Model; + + setKeyContents(keyContents:string):void; + + setKeyContents(keyContents:number):void; + + setKeyContents(keyContents:Model):void; + + onChange(model:Model, attr:any, options:any):void; + + tryAddRelated(model:Model, coll:any, options:any):void; + + addRelated(model:Model, options:any):void; + + removeRelated(model:Model, coll:any, options:any):void; + + } + + export class Store extends Events { + initializeRelation(model, relation, options); + + addModelScope(scope:any):void; + + removeModelScope(scope):void; + + addSubModels(subModelTypes:RelationalModel, superModelType:RelationalModel):void; + + setupSuperModel(modelType:RelationalModel):void; + + addReverseRelation(relation:any):void; + + addOrphanRelation(relation:any):void; + + processOrphanRelations():void; + + retroFitRelation(relation:RelationalModel, create:bool):Collection; + + getCollection(type:RelationalModel, create:bool):Collection; + + getObjectByName(name:string):any; + + + resolveIdForItem(type:any, item:any):any; + + find(type:any, item:string):RelationalModel; + + find(type:any, item:number):RelationalModel; + + find(type:any, item:RelationalModel):RelationalModel; + + find(type:any, item:any):RelationalModel; + + register(model:RelationalModel):void; + + checkId(model:RelationalModel, id:any):void; + + update(model:RelationalModel):void; + + unregister(model:RelationalModel, collection:Collection, options:any):void; + + reset():void; + + + } + +} \ No newline at end of file From 0fea514200e85aad3fe2a63ebb15048ebee8e176 Mon Sep 17 00:00:00 2001 From: Eirik Hoem Date: Thu, 23 May 2013 12:51:52 +0200 Subject: [PATCH 2/5] Added tests for Backbone Relational, updated README --- README.md | 1 + .../backbone-relational-test.ts | 121 ++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 backbone-relational/backbone-relational-test.ts diff --git a/README.md b/README.md index ec2bec078..60dd2152c 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ List of Definitions * [AngularJS](http://angularjs.org) (by [Diego Vilar](https://github.com/diegovilar)) ([wiki](https://github.com/borisyankov/DefinitelyTyped/wiki/AngularJS-Definitions-Usage-Notes)) * [async](https://github.com/caolan/async) (by [Boris Yankov](https://github.com/borisyankov)) * [Backbone.js](http://backbonejs.org/) (by [Boris Yankov](https://github.com/borisyankov)) +* [Backbone Relational](http://backbonerelational.org/) (by [Eirik Hoem](https://github.com/eirikhm)) * [Bootbox](https://github.com/makeusabrew/bootbox) (by [Vincent Bortone](https://github.com/vbortone/)) * [Bootstrap](http://twitter.github.com/bootstrap/) (by [Boris Yankov](https://github.com/borisyankov)) * [bootstrap-notify](https://github.com/Nijikokun/bootstrap-notify) (by [Blake Niemyjski](https://github.com/niemyjski)) diff --git a/backbone-relational/backbone-relational-test.ts b/backbone-relational/backbone-relational-test.ts new file mode 100644 index 000000000..f1eaffc02 --- /dev/null +++ b/backbone-relational/backbone-relational-test.ts @@ -0,0 +1,121 @@ +/// +/// + +class House extends Backbone.RelationalModel { + // The 'relations' property, on the House's prototype. Initialized separately for each + // instance of House. Each relation must define (as a minimum) the 'type', 'key' and + // 'relatedModel'. Options include 'includeInJSON', 'createModels' and 'reverseRelation'. + + relations = [ + { + type: Backbone.HasMany, // Use the type, or the string 'HasOne' or 'HasMany'. + key: 'occupants', + relatedModel: 'Person', + includeInJSON: Backbone.Model.prototype.idAttribute, + collectionType: 'PersonCollection', + reverseRelation: { + key: 'livesIn' + } + } + ]; + +} + +class Person extends Backbone.RelationalModel { + relations = [ + { // Create a (recursive) one-to-one relationship + type: Backbone.HasOne, + key: 'user', + relatedModel: 'User', + reverseRelation: { + type: Backbone.HasOne, + key: 'person' + } + } + ]; + + initialize() + { + // do whatever you want :) + } +} + +class PersonCollection extends Backbone.Collection { + url(models) + { + // Logic to create a url for the whole collection, or a set of models. + // See the tests, or Backbone-tastypie, for an example. + return '/person/' + ( models ? 'set/' + _.pluck(models, 'id').join(';') + '/' : '' ); + } +} + +class User extends Backbone.RelationalModel { + +} + + +var paul = new Person({ + id: 'person-1', + name: 'Paul', + user: { id: 'user-1', login: 'dude', email: 'me@gmail.com' } +}); + +// A User object is automatically created from the JSON; so 'login' returns 'dude'. +paul.get('user').get('login'); + +var ourHouse = new House({ + id: 'house-1', + location: 'in the middle of the street', + occupants: ['person-1', 'person-2', 'person-5'] +}); + +// 'ourHouse.occupants' is turned into a Backbone.Collection of Persons. +// The first person in 'ourHouse.occupants' will point to 'paul'. +ourHouse.get('occupants').at(0); // === paul + +// If a collection is created from a HasMany relation, it contains a reference +// back to the originator of the relation +ourHouse.get('occupants').livesIn; // === ourHouse + +// The `occupants` relation on 'House' has been defined as a HasMany, with a reverse relation +// to `livesIn` on 'Person'. So, 'paul.livesIn' will automatically point back to 'ourHouse'. +paul.get('livesIn'); // === ourHouse + +// You can control which relations get serialized to JSON, using the 'includeInJSON' +// property on a Relation. Also, each object will only get serialized once to prevent loops. +alert(JSON.stringify(paul.get('user').toJSON(), null, '\t')); +// Load occupants 'person-2' and 'person-5', which don't exist yet, from the server +ourHouse.fetchRelated('occupants'); + +// Use the `add` and `remove` events to listen for additions/removals on a HasMany relation. +// Here, we listen for changes to `ourHouse.occupants`. +ourHouse + .on('add:occupants', function (model, coll) + { + console.log('add %o', model); + // Do something. Create a View? + }) + .on('remove:occupants', function (model, coll) + { + console.log('remove %o', model); + // Do somehting. Destroy a View? + }); + +// Use the 'update' event to listen for changes on a HasOne relation (like 'Person.livesIn'). +paul.on('change:livesIn', function (model, attr) +{ + console.log('change `livesIn` to %o', attr); +}); + +// Modifying either side of a bi-directional relation updates the other side automatically. +// Take `paul` out or `ourHouse`; this triggers `remove:occupants` on `ourHouse`, +// and `change:livesIn` on `paul` +ourHouse.get('occupants').remove(paul); + +alert('paul.livesIn=' + paul.get('livesIn')); +// Move into `theirHouse`; triggers 'add:occupants' on ourHouse, and 'change:livesIn' on paul + +var theirHouse = new House({ id: 'house-2' }); +paul.set({ 'livesIn': theirHouse }); + +alert('theirHouse.occupants=' + theirHouse.get('occupants').pluck('name')); \ No newline at end of file From aa7188013a2902e54358d564030cb610b9a3afb4 Mon Sep 17 00:00:00 2001 From: Eirik Hoem Date: Thu, 23 May 2013 13:30:28 +0200 Subject: [PATCH 3/5] Renamed tests file --- .../{backbone-relational-test.ts => backbone-relational-tests.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename backbone-relational/{backbone-relational-test.ts => backbone-relational-tests.ts} (100%) diff --git a/backbone-relational/backbone-relational-test.ts b/backbone-relational/backbone-relational-tests.ts similarity index 100% rename from backbone-relational/backbone-relational-test.ts rename to backbone-relational/backbone-relational-tests.ts From b64194b52f0505e0c5ab5f398d080b7d4acf795b Mon Sep 17 00:00:00 2001 From: Eirik Hoem Date: Thu, 23 May 2013 13:34:57 +0200 Subject: [PATCH 4/5] Updated test, not referencing Model anymore --- backbone-relational/backbone-relational-tests.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backbone-relational/backbone-relational-tests.ts b/backbone-relational/backbone-relational-tests.ts index f1eaffc02..acc31417b 100644 --- a/backbone-relational/backbone-relational-tests.ts +++ b/backbone-relational/backbone-relational-tests.ts @@ -11,7 +11,7 @@ class House extends Backbone.RelationalModel { type: Backbone.HasMany, // Use the type, or the string 'HasOne' or 'HasMany'. key: 'occupants', relatedModel: 'Person', - includeInJSON: Backbone.Model.prototype.idAttribute, + includeInJSON: true, collectionType: 'PersonCollection', reverseRelation: { key: 'livesIn' From 0189ba4515c931515b11e2abbab6360555b4bc1c Mon Sep 17 00:00:00 2001 From: Eirik Hoem Date: Thu, 23 May 2013 13:36:15 +0200 Subject: [PATCH 5/5] Added reference to Underscore --- backbone-relational/backbone-relational-tests.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/backbone-relational/backbone-relational-tests.ts b/backbone-relational/backbone-relational-tests.ts index acc31417b..606bfdf19 100644 --- a/backbone-relational/backbone-relational-tests.ts +++ b/backbone-relational/backbone-relational-tests.ts @@ -1,4 +1,5 @@ /// +/// /// class House extends Backbone.RelationalModel {