server/python/django/renkanmanager/static/renkanmanager/lib/backbone-relational.js
author cavaliet
Tue, 22 Jul 2014 18:01:03 +0200
changeset 318 815589aed866
permissions -rw-r--r--
django app renkamanager (models, vanilla views, utils, static files)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
318
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
     1
/* vim: set tabstop=4 softtabstop=4 shiftwidth=4 noexpandtab: */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
     2
/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
     3
 * Backbone-relational.js 0.8.5
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
     4
 * (c) 2011-2013 Paul Uithol and contributors (https://github.com/PaulUithol/Backbone-relational/graphs/contributors)
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
     5
 * 
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
     6
 * Backbone-relational may be freely distributed under the MIT license; see the accompanying LICENSE.txt.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
     7
 * For details and documentation: https://github.com/PaulUithol/Backbone-relational.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
     8
 * Depends on Backbone (and thus on Underscore as well): https://github.com/documentcloud/backbone.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
     9
 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    10
( function( undefined ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    11
	"use strict";
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    12
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    13
	/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    14
	 * CommonJS shim
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    15
	 **/
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    16
	var _, Backbone, exports;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    17
	if ( typeof window === 'undefined' ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    18
		_ = require( 'underscore' );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    19
		Backbone = require( 'backbone' );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    20
		exports = module.exports = Backbone;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    21
	}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    22
	else {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    23
		_ = window._;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    24
		Backbone = window.Backbone;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    25
		exports = window;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    26
	}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    27
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    28
	Backbone.Relational = {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    29
		showWarnings: true
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    30
	};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    31
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    32
	/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    33
	 * Semaphore mixin; can be used as both binary and counting.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    34
	 **/
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    35
	Backbone.Semaphore = {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    36
		_permitsAvailable: null,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    37
		_permitsUsed: 0,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    38
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    39
		acquire: function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    40
			if ( this._permitsAvailable && this._permitsUsed >= this._permitsAvailable ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    41
				throw new Error( 'Max permits acquired' );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    42
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    43
			else {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    44
				this._permitsUsed++;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    45
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    46
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    47
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    48
		release: function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    49
			if ( this._permitsUsed === 0 ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    50
				throw new Error( 'All permits released' );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    51
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    52
			else {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    53
				this._permitsUsed--;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    54
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    55
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    56
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    57
		isLocked: function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    58
			return this._permitsUsed > 0;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    59
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    60
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    61
		setAvailablePermits: function( amount ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    62
			if ( this._permitsUsed > amount ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    63
				throw new Error( 'Available permits cannot be less than used permits' );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    64
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    65
			this._permitsAvailable = amount;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    66
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    67
	};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    68
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    69
	/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    70
	 * A BlockingQueue that accumulates items while blocked (via 'block'),
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    71
	 * and processes them when unblocked (via 'unblock').
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    72
	 * Process can also be called manually (via 'process').
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    73
	 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    74
	Backbone.BlockingQueue = function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    75
		this._queue = [];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    76
	};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    77
	_.extend( Backbone.BlockingQueue.prototype, Backbone.Semaphore, {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    78
		_queue: null,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    79
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    80
		add: function( func ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    81
			if ( this.isBlocked() ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    82
				this._queue.push( func );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    83
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    84
			else {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    85
				func();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    86
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    87
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    88
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    89
		process: function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    90
			while ( this._queue && this._queue.length ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    91
				this._queue.shift()();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    92
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    93
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    94
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    95
		block: function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    96
			this.acquire();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    97
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    98
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
    99
		unblock: function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   100
			this.release();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   101
			if ( !this.isBlocked() ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   102
				this.process();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   103
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   104
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   105
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   106
		isBlocked: function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   107
			return this.isLocked();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   108
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   109
	});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   110
	/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   111
	 * Global event queue. Accumulates external events ('add:<key>', 'remove:<key>' and 'change:<key>')
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   112
	 * until the top-level object is fully initialized (see 'Backbone.RelationalModel').
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   113
	 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   114
	Backbone.Relational.eventQueue = new Backbone.BlockingQueue();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   115
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   116
	/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   117
	 * Backbone.Store keeps track of all created (and destruction of) Backbone.RelationalModel.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   118
	 * Handles lookup for relations.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   119
	 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   120
	Backbone.Store = function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   121
		this._collections = [];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   122
		this._reverseRelations = [];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   123
		this._orphanRelations = [];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   124
		this._subModels = [];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   125
		this._modelScopes = [ exports ];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   126
	};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   127
	_.extend( Backbone.Store.prototype, Backbone.Events, {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   128
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   129
		 * Create a new `Relation`.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   130
		 * @param {Backbone.RelationalModel} [model]
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   131
		 * @param {Object} relation
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   132
		 * @param {Object} [options]
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   133
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   134
		initializeRelation: function( model, relation, options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   135
			var type = !_.isString( relation.type ) ? relation.type : Backbone[ relation.type ] || this.getObjectByName( relation.type );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   136
			if ( type && type.prototype instanceof Backbone.Relation ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   137
				new type( model, relation, options ); // Also pushes the new Relation into `model._relations`
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   138
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   139
			else {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   140
				Backbone.Relational.showWarnings && typeof console !== 'undefined' && console.warn( 'Relation=%o; missing or invalid relation type!', relation );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   141
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   142
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   143
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   144
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   145
		 * Add a scope for `getObjectByName` to look for model types by name.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   146
		 * @param {Object} scope
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   147
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   148
		addModelScope: function( scope ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   149
			this._modelScopes.push( scope );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   150
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   151
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   152
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   153
		 * Remove a scope.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   154
		 * @param {Object} scope
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   155
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   156
		removeModelScope: function( scope ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   157
			this._modelScopes = _.without( this._modelScopes, scope );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   158
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   159
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   160
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   161
		 * Add a set of subModelTypes to the store, that can be used to resolve the '_superModel'
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   162
		 * for a model later in 'setupSuperModel'.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   163
		 *
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   164
		 * @param {Backbone.RelationalModel} subModelTypes
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   165
		 * @param {Backbone.RelationalModel} superModelType
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   166
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   167
		addSubModels: function( subModelTypes, superModelType ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   168
			this._subModels.push({
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   169
				'superModelType': superModelType,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   170
				'subModels': subModelTypes
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   171
			});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   172
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   173
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   174
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   175
		 * Check if the given modelType is registered as another model's subModel. If so, add it to the super model's
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   176
		 * '_subModels', and set the modelType's '_superModel', '_subModelTypeName', and '_subModelTypeAttribute'.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   177
		 *
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   178
		 * @param {Backbone.RelationalModel} modelType
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   179
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   180
		setupSuperModel: function( modelType ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   181
			_.find( this._subModels, function( subModelDef ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   182
				return _.find( subModelDef.subModels || [], function( subModelTypeName, typeValue ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   183
					var subModelType = this.getObjectByName( subModelTypeName );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   184
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   185
					if ( modelType === subModelType ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   186
						// Set 'modelType' as a child of the found superModel
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   187
						subModelDef.superModelType._subModels[ typeValue ] = modelType;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   188
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   189
						// Set '_superModel', '_subModelTypeValue', and '_subModelTypeAttribute' on 'modelType'.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   190
						modelType._superModel = subModelDef.superModelType;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   191
						modelType._subModelTypeValue = typeValue;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   192
						modelType._subModelTypeAttribute = subModelDef.superModelType.prototype.subModelTypeAttribute;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   193
						return true;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   194
					}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   195
				}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   196
			}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   197
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   198
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   199
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   200
		 * Add a reverse relation. Is added to the 'relations' property on model's prototype, and to
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   201
		 * existing instances of 'model' in the store as well.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   202
		 * @param {Object} relation
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   203
		 * @param {Backbone.RelationalModel} relation.model
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   204
		 * @param {String} relation.type
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   205
		 * @param {String} relation.key
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   206
		 * @param {String|Object} relation.relatedModel
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   207
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   208
		addReverseRelation: function( relation ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   209
			var exists = _.any( this._reverseRelations, function( rel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   210
				return _.all( relation || [], function( val, key ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   211
					return val === rel[ key ];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   212
				});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   213
			});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   214
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   215
			if ( !exists && relation.model && relation.type ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   216
				this._reverseRelations.push( relation );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   217
				this._addRelation( relation.model, relation );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   218
				this.retroFitRelation( relation );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   219
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   220
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   221
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   222
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   223
		 * Deposit a `relation` for which the `relatedModel` can't be resolved at the moment.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   224
		 *
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   225
		 * @param {Object} relation
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   226
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   227
		addOrphanRelation: function( relation ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   228
			var exists = _.any( this._orphanRelations, function( rel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   229
				return _.all( relation || [], function( val, key ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   230
					return val === rel[ key ];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   231
				});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   232
			});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   233
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   234
			if ( !exists && relation.model && relation.type ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   235
				this._orphanRelations.push( relation );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   236
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   237
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   238
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   239
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   240
		 * Try to initialize any `_orphanRelation`s
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   241
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   242
		processOrphanRelations: function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   243
			// Make sure to operate on a copy since we're removing while iterating
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   244
			_.each( this._orphanRelations.slice( 0 ), function( rel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   245
				var relatedModel = Backbone.Relational.store.getObjectByName( rel.relatedModel );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   246
				if ( relatedModel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   247
					this.initializeRelation( null, rel );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   248
					this._orphanRelations = _.without( this._orphanRelations, rel );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   249
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   250
			}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   251
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   252
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   253
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   254
		 *
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   255
		 * @param {Backbone.RelationalModel.constructor} type
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   256
		 * @param {Object} relation
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   257
		 * @private
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   258
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   259
		_addRelation: function( type, relation ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   260
			if ( !type.prototype.relations ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   261
				type.prototype.relations = [];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   262
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   263
			type.prototype.relations.push( relation );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   264
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   265
			_.each( type._subModels || [], function( subModel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   266
				this._addRelation( subModel, relation );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   267
			}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   268
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   269
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   270
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   271
		 * Add a 'relation' to all existing instances of 'relation.model' in the store
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   272
		 * @param {Object} relation
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   273
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   274
		retroFitRelation: function( relation ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   275
			var coll = this.getCollection( relation.model, false );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   276
			coll && coll.each( function( model ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   277
				if ( !( model instanceof relation.model ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   278
					return;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   279
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   280
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   281
				new relation.type( model, relation );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   282
			}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   283
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   284
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   285
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   286
		 * Find the Store's collection for a certain type of model.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   287
		 * @param {Backbone.RelationalModel} type
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   288
		 * @param {Boolean} [create=true] Should a collection be created if none is found?
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   289
		 * @return {Backbone.Collection} A collection if found (or applicable for 'model'), or null
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   290
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   291
		getCollection: function( type, create ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   292
			if ( type instanceof Backbone.RelationalModel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   293
				type = type.constructor;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   294
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   295
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   296
			var rootModel = type;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   297
			while ( rootModel._superModel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   298
				rootModel = rootModel._superModel;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   299
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   300
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   301
			var coll = _.findWhere( this._collections, { model: rootModel } );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   302
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   303
			if ( !coll && create !== false ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   304
				coll = this._createCollection( rootModel );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   305
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   306
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   307
			return coll;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   308
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   309
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   310
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   311
		 * Find a model type on one of the modelScopes by name. Names are split on dots.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   312
		 * @param {String} name
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   313
		 * @return {Object}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   314
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   315
		getObjectByName: function( name ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   316
			var parts = name.split( '.' ),
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   317
				type = null;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   318
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   319
			_.find( this._modelScopes, function( scope ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   320
				type = _.reduce( parts || [], function( memo, val ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   321
					return memo ? memo[ val ] : undefined;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   322
				}, scope );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   323
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   324
				if ( type && type !== scope ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   325
					return true;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   326
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   327
			}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   328
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   329
			return type;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   330
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   331
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   332
		_createCollection: function( type ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   333
			var coll;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   334
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   335
			// If 'type' is an instance, take its constructor
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   336
			if ( type instanceof Backbone.RelationalModel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   337
				type = type.constructor;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   338
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   339
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   340
			// Type should inherit from Backbone.RelationalModel.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   341
			if ( type.prototype instanceof Backbone.RelationalModel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   342
				coll = new Backbone.Collection();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   343
				coll.model = type;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   344
				
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   345
				this._collections.push( coll );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   346
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   347
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   348
			return coll;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   349
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   350
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   351
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   352
		 * Find the attribute that is to be used as the `id` on a given object
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   353
		 * @param type
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   354
		 * @param {String|Number|Object|Backbone.RelationalModel} item
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   355
		 * @return {String|Number}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   356
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   357
		resolveIdForItem: function( type, item ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   358
			var id = _.isString( item ) || _.isNumber( item ) ? item : null;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   359
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   360
			if ( id === null ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   361
				if ( item instanceof Backbone.RelationalModel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   362
					id = item.id;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   363
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   364
				else if ( _.isObject( item ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   365
					id = item[ type.prototype.idAttribute ];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   366
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   367
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   368
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   369
			// Make all falsy values `null` (except for 0, which could be an id.. see '/issues/179')
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   370
			if ( !id && id !== 0 ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   371
				id = null;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   372
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   373
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   374
			return id;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   375
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   376
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   377
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   378
		 * Find a specific model of a certain `type` in the store
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   379
		 * @param type
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   380
		 * @param {String|Number|Object|Backbone.RelationalModel} item
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   381
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   382
		find: function( type, item ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   383
			var id = this.resolveIdForItem( type, item );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   384
			var coll = this.getCollection( type );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   385
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   386
			// Because the found object could be of any of the type's superModel
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   387
			// types, only return it if it's actually of the type asked for.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   388
			if ( coll ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   389
				var obj = coll.get( id );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   390
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   391
				if ( obj instanceof type ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   392
					return obj;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   393
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   394
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   395
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   396
			return null;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   397
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   398
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   399
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   400
		 * Add a 'model' to its appropriate collection. Retain the original contents of 'model.collection'.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   401
		 * @param {Backbone.RelationalModel} model
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   402
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   403
		register: function( model ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   404
			var coll = this.getCollection( model );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   405
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   406
			if ( coll ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   407
				var modelColl = model.collection;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   408
				coll.add( model );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   409
				this.listenTo( model, 'destroy', this.unregister, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   410
				model.collection = modelColl;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   411
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   412
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   413
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   414
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   415
		 * Check if the given model may use the given `id`
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   416
		 * @param model
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   417
		 * @param [id]
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   418
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   419
		checkId: function( model, id ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   420
			var coll = this.getCollection( model ),
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   421
				duplicate = coll && coll.get( id );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   422
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   423
			if ( duplicate && model !== duplicate ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   424
				if ( Backbone.Relational.showWarnings && typeof console !== 'undefined' ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   425
					console.warn( 'Duplicate id! Old RelationalModel=%o, new RelationalModel=%o', duplicate, model );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   426
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   427
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   428
				throw new Error( "Cannot instantiate more than one Backbone.RelationalModel with the same id per type!" );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   429
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   430
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   431
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   432
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   433
		 * Explicitly update a model's id in its store collection
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   434
		 * @param {Backbone.RelationalModel} model
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   435
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   436
		update: function( model ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   437
			var coll = this.getCollection( model );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   438
			// This triggers updating the lookup indices kept in a collection
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   439
			coll._onModelEvent( 'change:' + model.idAttribute, model, coll );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   440
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   441
			// Trigger an event on model so related models (having the model's new id in their keyContents) can add it.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   442
			model.trigger( 'relational:change:id', model, coll );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   443
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   444
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   445
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   446
		 * Remove a 'model' from the store.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   447
		 * @param {Backbone.RelationalModel} model
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   448
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   449
		unregister: function( model ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   450
			this.stopListening( model, 'destroy', this.unregister );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   451
			var coll = this.getCollection( model );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   452
			coll && coll.remove( model );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   453
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   454
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   455
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   456
		 * Reset the `store` to it's original state. The `reverseRelations` are kept though, since attempting to
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   457
		 * re-initialize these on models would lead to a large amount of warnings.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   458
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   459
		reset: function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   460
			this.stopListening();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   461
			this._collections = [];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   462
			this._subModels = [];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   463
			this._modelScopes = [ exports ];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   464
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   465
	});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   466
	Backbone.Relational.store = new Backbone.Store();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   467
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   468
	/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   469
	 * The main Relation class, from which 'HasOne' and 'HasMany' inherit. Internally, 'relational:<key>' events
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   470
	 * are used to regulate addition and removal of models from relations.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   471
	 *
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   472
	 * @param {Backbone.RelationalModel} [instance] Model that this relation is created for. If no model is supplied,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   473
	 *      Relation just tries to instantiate it's `reverseRelation` if specified, and bails out after that.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   474
	 * @param {Object} options
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   475
	 * @param {string} options.key
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   476
	 * @param {Backbone.RelationalModel.constructor} options.relatedModel
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   477
	 * @param {Boolean|String} [options.includeInJSON=true] Serialize the given attribute for related model(s)' in toJSON, or just their ids.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   478
	 * @param {Boolean} [options.createModels=true] Create objects from the contents of keys if the object is not found in Backbone.store.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   479
	 * @param {Object} [options.reverseRelation] Specify a bi-directional relation. If provided, Relation will reciprocate
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   480
	 *    the relation to the 'relatedModel'. Required and optional properties match 'options', except that it also needs
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   481
	 *    {Backbone.Relation|String} type ('HasOne' or 'HasMany').
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   482
	 * @param {Object} opts
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   483
	 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   484
	Backbone.Relation = function( instance, options, opts ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   485
		this.instance = instance;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   486
		// Make sure 'options' is sane, and fill with defaults from subclasses and this object's prototype
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   487
		options = _.isObject( options ) ? options : {};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   488
		this.reverseRelation = _.defaults( options.reverseRelation || {}, this.options.reverseRelation );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   489
		this.options = _.defaults( options, this.options, Backbone.Relation.prototype.options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   490
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   491
		this.reverseRelation.type = !_.isString( this.reverseRelation.type ) ? this.reverseRelation.type :
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   492
			Backbone[ this.reverseRelation.type ] || Backbone.Relational.store.getObjectByName( this.reverseRelation.type );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   493
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   494
		this.key = this.options.key;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   495
		this.keySource = this.options.keySource || this.key;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   496
		this.keyDestination = this.options.keyDestination || this.keySource || this.key;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   497
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   498
		this.model = this.options.model || this.instance.constructor;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   499
		this.relatedModel = this.options.relatedModel;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   500
		if ( _.isString( this.relatedModel ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   501
			this.relatedModel = Backbone.Relational.store.getObjectByName( this.relatedModel );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   502
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   503
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   504
		if ( !this.checkPreconditions() ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   505
			return;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   506
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   507
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   508
		// Add the reverse relation on 'relatedModel' to the store's reverseRelations
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   509
		if ( !this.options.isAutoRelation && this.reverseRelation.type && this.reverseRelation.key ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   510
			Backbone.Relational.store.addReverseRelation( _.defaults( {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   511
					isAutoRelation: true,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   512
					model: this.relatedModel,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   513
					relatedModel: this.model,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   514
					reverseRelation: this.options // current relation is the 'reverseRelation' for its own reverseRelation
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   515
				},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   516
				this.reverseRelation // Take further properties from this.reverseRelation (type, key, etc.)
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   517
			) );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   518
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   519
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   520
		if ( instance ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   521
			var contentKey = this.keySource;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   522
			if ( contentKey !== this.key && typeof this.instance.get( this.key ) === 'object' ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   523
				contentKey = this.key;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   524
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   525
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   526
			this.setKeyContents( this.instance.get( contentKey ) );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   527
			this.relatedCollection = Backbone.Relational.store.getCollection( this.relatedModel );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   528
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   529
			// Explicitly clear 'keySource', to prevent a leaky abstraction if 'keySource' differs from 'key'.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   530
			if ( this.keySource !== this.key ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   531
				this.instance.unset( this.keySource, { silent: true } );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   532
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   533
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   534
			// Add this Relation to instance._relations
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   535
			this.instance._relations[ this.key ] = this;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   536
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   537
			this.initialize( opts );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   538
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   539
			if ( this.options.autoFetch ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   540
				this.instance.fetchRelated( this.key, _.isObject( this.options.autoFetch ) ? this.options.autoFetch : {} );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   541
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   542
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   543
			// When 'relatedModel' are created or destroyed, check if it affects this relation.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   544
			this.listenTo( this.instance, 'destroy', this.destroy )
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   545
				.listenTo( this.relatedCollection, 'relational:add relational:change:id', this.tryAddRelated )
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   546
				.listenTo( this.relatedCollection, 'relational:remove', this.removeRelated )
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   547
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   548
	};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   549
	// Fix inheritance :\
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   550
	Backbone.Relation.extend = Backbone.Model.extend;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   551
	// Set up all inheritable **Backbone.Relation** properties and methods.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   552
	_.extend( Backbone.Relation.prototype, Backbone.Events, Backbone.Semaphore, {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   553
		options: {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   554
			createModels: true,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   555
			includeInJSON: true,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   556
			isAutoRelation: false,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   557
			autoFetch: false,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   558
			parse: false
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   559
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   560
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   561
		instance: null,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   562
		key: null,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   563
		keyContents: null,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   564
		relatedModel: null,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   565
		relatedCollection: null,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   566
		reverseRelation: null,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   567
		related: null,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   568
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   569
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   570
		 * Check several pre-conditions.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   571
		 * @return {Boolean} True if pre-conditions are satisfied, false if they're not.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   572
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   573
		checkPreconditions: function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   574
			var i = this.instance,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   575
				k = this.key,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   576
				m = this.model,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   577
				rm = this.relatedModel,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   578
				warn = Backbone.Relational.showWarnings && typeof console !== 'undefined';
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   579
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   580
			if ( !m || !k || !rm ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   581
				warn && console.warn( 'Relation=%o: missing model, key or relatedModel (%o, %o, %o).', this, m, k, rm );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   582
				return false;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   583
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   584
			// Check if the type in 'model' inherits from Backbone.RelationalModel
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   585
			if ( !( m.prototype instanceof Backbone.RelationalModel ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   586
				warn && console.warn( 'Relation=%o: model does not inherit from Backbone.RelationalModel (%o).', this, i );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   587
				return false;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   588
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   589
			// Check if the type in 'relatedModel' inherits from Backbone.RelationalModel
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   590
			if ( !( rm.prototype instanceof Backbone.RelationalModel ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   591
				warn && console.warn( 'Relation=%o: relatedModel does not inherit from Backbone.RelationalModel (%o).', this, rm );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   592
				return false;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   593
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   594
			// Check if this is not a HasMany, and the reverse relation is HasMany as well
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   595
			if ( this instanceof Backbone.HasMany && this.reverseRelation.type === Backbone.HasMany ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   596
				warn && console.warn( 'Relation=%o: relation is a HasMany, and the reverseRelation is HasMany as well.', this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   597
				return false;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   598
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   599
			// Check if we're not attempting to create a relationship on a `key` that's already used.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   600
			if ( i && _.keys( i._relations ).length ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   601
				var existing = _.find( i._relations, function( rel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   602
					return rel.key === k;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   603
				}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   604
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   605
				if ( existing ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   606
					warn && console.warn( 'Cannot create relation=%o on %o for model=%o: already taken by relation=%o.',
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   607
						this, k, i, existing );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   608
					return false;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   609
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   610
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   611
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   612
			return true;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   613
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   614
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   615
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   616
		 * Set the related model(s) for this relation
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   617
		 * @param {Backbone.Model|Backbone.Collection} related
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   618
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   619
		setRelated: function( related ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   620
			this.related = related;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   621
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   622
			this.instance.acquire();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   623
			this.instance.attributes[ this.key ] = related;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   624
			this.instance.release();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   625
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   626
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   627
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   628
		 * Determine if a relation (on a different RelationalModel) is the reverse
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   629
		 * relation of the current one.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   630
		 * @param {Backbone.Relation} relation
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   631
		 * @return {Boolean}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   632
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   633
		_isReverseRelation: function( relation ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   634
			return relation.instance instanceof this.relatedModel && this.reverseRelation.key === relation.key &&
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   635
				this.key === relation.reverseRelation.key;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   636
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   637
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   638
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   639
		 * Get the reverse relations (pointing back to 'this.key' on 'this.instance') for the currently related model(s).
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   640
		 * @param {Backbone.RelationalModel} [model] Get the reverse relations for a specific model.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   641
		 *    If not specified, 'this.related' is used.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   642
		 * @return {Backbone.Relation[]}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   643
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   644
		getReverseRelations: function( model ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   645
			var reverseRelations = [];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   646
			// Iterate over 'model', 'this.related.models' (if this.related is a Backbone.Collection), or wrap 'this.related' in an array.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   647
			var models = !_.isUndefined( model ) ? [ model ] : this.related && ( this.related.models || [ this.related ] );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   648
			_.each( models || [], function( related ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   649
				_.each( related.getRelations() || [], function( relation ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   650
						if ( this._isReverseRelation( relation ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   651
							reverseRelations.push( relation );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   652
						}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   653
					}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   654
			}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   655
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   656
			return reverseRelations;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   657
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   658
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   659
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   660
		 * When `this.instance` is destroyed, cleanup our relations.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   661
		 * Get reverse relation, call removeRelated on each.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   662
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   663
		destroy: function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   664
			this.stopListening();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   665
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   666
			if ( this instanceof Backbone.HasOne ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   667
				this.setRelated( null );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   668
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   669
			else if ( this instanceof Backbone.HasMany ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   670
				this.setRelated( this._prepareCollection() );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   671
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   672
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   673
			_.each( this.getReverseRelations(), function( relation ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   674
				relation.removeRelated( this.instance );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   675
			}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   676
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   677
	});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   678
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   679
	Backbone.HasOne = Backbone.Relation.extend({
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   680
		options: {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   681
			reverseRelation: { type: 'HasMany' }
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   682
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   683
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   684
		initialize: function( opts ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   685
			this.listenTo( this.instance, 'relational:change:' + this.key, this.onChange );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   686
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   687
			var related = this.findRelated( opts );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   688
			this.setRelated( related );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   689
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   690
			// Notify new 'related' object of the new relation.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   691
			_.each( this.getReverseRelations(), function( relation ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   692
				relation.addRelated( this.instance, opts );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   693
			}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   694
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   695
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   696
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   697
		 * Find related Models.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   698
		 * @param {Object} [options]
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   699
		 * @return {Backbone.Model}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   700
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   701
		findRelated: function( options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   702
			var related = null;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   703
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   704
			options = _.defaults( { parse: this.options.parse }, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   705
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   706
			if ( this.keyContents instanceof this.relatedModel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   707
				related = this.keyContents;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   708
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   709
			else if ( this.keyContents || this.keyContents === 0 ) { // since 0 can be a valid `id` as well
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   710
				var opts = _.defaults( { create: this.options.createModels }, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   711
				related = this.relatedModel.findOrCreate( this.keyContents, opts );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   712
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   713
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   714
			// Nullify `keyId` if we have a related model; in case it was already part of the relation
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   715
			if ( this.related ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   716
				this.keyId = null;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   717
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   718
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   719
			return related;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   720
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   721
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   722
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   723
		 * Normalize and reduce `keyContents` to an `id`, for easier comparison
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   724
		 * @param {String|Number|Backbone.Model} keyContents
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   725
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   726
		setKeyContents: function( keyContents ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   727
			this.keyContents = keyContents;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   728
			this.keyId = Backbone.Relational.store.resolveIdForItem( this.relatedModel, this.keyContents );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   729
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   730
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   731
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   732
		 * Event handler for `change:<key>`.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   733
		 * If the key is changed, notify old & new reverse relations and initialize the new relation.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   734
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   735
		onChange: function( model, attr, options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   736
			// Don't accept recursive calls to onChange (like onChange->findRelated->findOrCreate->initializeRelations->addRelated->onChange)
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   737
			if ( this.isLocked() ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   738
				return;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   739
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   740
			this.acquire();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   741
			options = options ? _.clone( options ) : {};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   742
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   743
			// 'options.__related' is set by 'addRelated'/'removeRelated'. If it is set, the change
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   744
			// is the result of a call from a relation. If it's not, the change is the result of 
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   745
			// a 'set' call on this.instance.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   746
			var changed = _.isUndefined( options.__related ),
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   747
				oldRelated = changed ? this.related : options.__related;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   748
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   749
			if ( changed ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   750
				this.setKeyContents( attr );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   751
				var related = this.findRelated( options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   752
				this.setRelated( related );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   753
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   754
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   755
			// Notify old 'related' object of the terminated relation
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   756
			if ( oldRelated && this.related !== oldRelated ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   757
				_.each( this.getReverseRelations( oldRelated ), function( relation ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   758
					relation.removeRelated( this.instance, null, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   759
				}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   760
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   761
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   762
			// Notify new 'related' object of the new relation. Note we do re-apply even if this.related is oldRelated;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   763
			// that can be necessary for bi-directional relations if 'this.instance' was created after 'this.related'.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   764
			// In that case, 'this.instance' will already know 'this.related', but the reverse might not exist yet.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   765
			_.each( this.getReverseRelations(), function( relation ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   766
				relation.addRelated( this.instance, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   767
			}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   768
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   769
			// Fire the 'change:<key>' event if 'related' was updated
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   770
			if ( !options.silent && this.related !== oldRelated ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   771
				var dit = this;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   772
				this.changed = true;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   773
				Backbone.Relational.eventQueue.add( function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   774
					dit.instance.trigger( 'change:' + dit.key, dit.instance, dit.related, options, true );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   775
					dit.changed = false;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   776
				});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   777
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   778
			this.release();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   779
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   780
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   781
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   782
		 * If a new 'this.relatedModel' appears in the 'store', try to match it to the last set 'keyContents'
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   783
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   784
		tryAddRelated: function( model, coll, options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   785
			if ( ( this.keyId || this.keyId === 0 ) && model.id === this.keyId ) { // since 0 can be a valid `id` as well
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   786
				this.addRelated( model, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   787
				this.keyId = null;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   788
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   789
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   790
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   791
		addRelated: function( model, options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   792
			// Allow 'model' to set up its relations before proceeding.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   793
			// (which can result in a call to 'addRelated' from a relation of 'model')
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   794
			var dit = this;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   795
			model.queue( function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   796
				if ( model !== dit.related ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   797
					var oldRelated = dit.related || null;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   798
					dit.setRelated( model );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   799
					dit.onChange( dit.instance, model, _.defaults( { __related: oldRelated }, options ) );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   800
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   801
			});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   802
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   803
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   804
		removeRelated: function( model, coll, options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   805
			if ( !this.related ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   806
				return;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   807
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   808
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   809
			if ( model === this.related ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   810
				var oldRelated = this.related || null;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   811
				this.setRelated( null );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   812
				this.onChange( this.instance, model, _.defaults( { __related: oldRelated }, options ) );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   813
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   814
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   815
	});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   816
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   817
	Backbone.HasMany = Backbone.Relation.extend({
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   818
		collectionType: null,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   819
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   820
		options: {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   821
			reverseRelation: { type: 'HasOne' },
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   822
			collectionType: Backbone.Collection,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   823
			collectionKey: true,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   824
			collectionOptions: {}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   825
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   826
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   827
		initialize: function( opts ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   828
			this.listenTo( this.instance, 'relational:change:' + this.key, this.onChange );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   829
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   830
			// Handle a custom 'collectionType'
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   831
			this.collectionType = this.options.collectionType;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   832
			if ( _.isString( this.collectionType ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   833
				this.collectionType = Backbone.Relational.store.getObjectByName( this.collectionType );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   834
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   835
			if ( this.collectionType !== Backbone.Collection && !( this.collectionType.prototype instanceof Backbone.Collection ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   836
				throw new Error( '`collectionType` must inherit from Backbone.Collection' );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   837
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   838
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   839
			var related = this.findRelated( opts );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   840
			this.setRelated( related );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   841
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   842
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   843
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   844
		 * Bind events and setup collectionKeys for a collection that is to be used as the backing store for a HasMany.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   845
		 * If no 'collection' is supplied, a new collection will be created of the specified 'collectionType' option.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   846
		 * @param {Backbone.Collection} [collection]
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   847
		 * @return {Backbone.Collection}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   848
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   849
		_prepareCollection: function( collection ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   850
			if ( this.related ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   851
				this.stopListening( this.related );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   852
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   853
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   854
			if ( !collection || !( collection instanceof Backbone.Collection ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   855
				var options = _.isFunction( this.options.collectionOptions ) ?
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   856
					this.options.collectionOptions( this.instance ) : this.options.collectionOptions;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   857
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   858
				collection = new this.collectionType( null, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   859
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   860
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   861
			collection.model = this.relatedModel;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   862
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   863
			if ( this.options.collectionKey ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   864
				var key = this.options.collectionKey === true ? this.options.reverseRelation.key : this.options.collectionKey;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   865
				
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   866
				if ( collection[ key ] && collection[ key ] !== this.instance ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   867
					if ( Backbone.Relational.showWarnings && typeof console !== 'undefined' ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   868
						console.warn( 'Relation=%o; collectionKey=%s already exists on collection=%o', this, key, this.options.collectionKey );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   869
					}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   870
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   871
				else if ( key ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   872
					collection[ key ] = this.instance;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   873
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   874
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   875
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   876
			this.listenTo( collection, 'relational:add', this.handleAddition )
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   877
				.listenTo( collection, 'relational:remove', this.handleRemoval )
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   878
				.listenTo( collection, 'relational:reset', this.handleReset );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   879
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   880
			return collection;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   881
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   882
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   883
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   884
		 * Find related Models.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   885
		 * @param {Object} [options]
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   886
		 * @return {Backbone.Collection}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   887
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   888
		findRelated: function( options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   889
			var related = null;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   890
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   891
			options = _.defaults( { parse: this.options.parse }, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   892
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   893
			// Replace 'this.related' by 'this.keyContents' if it is a Backbone.Collection
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   894
			if ( this.keyContents instanceof Backbone.Collection ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   895
				this._prepareCollection( this.keyContents );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   896
				related = this.keyContents;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   897
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   898
			// Otherwise, 'this.keyContents' should be an array of related object ids.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   899
			// Re-use the current 'this.related' if it is a Backbone.Collection; otherwise, create a new collection.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   900
			else {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   901
				var toAdd = [];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   902
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   903
				_.each( this.keyContents, function( attributes ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   904
					if ( attributes instanceof this.relatedModel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   905
						var model = attributes;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   906
					}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   907
					else {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   908
						// If `merge` is true, update models here, instead of during update.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   909
						model = this.relatedModel.findOrCreate( attributes,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   910
							_.extend( { merge: true }, options, { create: this.options.createModels } )
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   911
						);
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   912
					}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   913
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   914
					model && toAdd.push( model );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   915
				}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   916
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   917
				if ( this.related instanceof Backbone.Collection ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   918
					related = this.related;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   919
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   920
				else {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   921
					related = this._prepareCollection();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   922
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   923
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   924
				// By now, both `merge` and `parse` will already have been executed for models if they were specified.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   925
				// Disable them to prevent additional calls.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   926
				related.set( toAdd, _.defaults( { merge: false, parse: false }, options ) );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   927
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   928
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   929
			// Remove entries from `keyIds` that were already part of the relation (and are thus 'unchanged')
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   930
			this.keyIds = _.difference( this.keyIds, _.pluck( related.models, 'id' ) );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   931
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   932
			return related;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   933
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   934
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   935
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   936
		 * Normalize and reduce `keyContents` to a list of `ids`, for easier comparison
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   937
		 * @param {String|Number|String[]|Number[]|Backbone.Collection} keyContents
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   938
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   939
		setKeyContents: function( keyContents ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   940
			this.keyContents = keyContents instanceof Backbone.Collection ? keyContents : null;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   941
			this.keyIds = [];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   942
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   943
			if ( !this.keyContents && ( keyContents || keyContents === 0 ) ) { // since 0 can be a valid `id` as well
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   944
				// Handle cases the an API/user supplies just an Object/id instead of an Array
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   945
				this.keyContents = _.isArray( keyContents ) ? keyContents : [ keyContents ];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   946
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   947
				_.each( this.keyContents, function( item ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   948
					var itemId = Backbone.Relational.store.resolveIdForItem( this.relatedModel, item );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   949
					if ( itemId || itemId === 0 ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   950
						this.keyIds.push( itemId );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   951
					}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   952
				}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   953
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   954
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   955
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   956
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   957
		 * Event handler for `change:<key>`.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   958
		 * If the contents of the key are changed, notify old & new reverse relations and initialize the new relation.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   959
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   960
		onChange: function( model, attr, options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   961
			options = options ? _.clone( options ) : {};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   962
			this.setKeyContents( attr );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   963
			this.changed = false;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   964
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   965
			var related = this.findRelated( options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   966
			this.setRelated( related );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   967
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   968
			if ( !options.silent ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   969
				var dit = this;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   970
				Backbone.Relational.eventQueue.add( function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   971
					// The `changed` flag can be set in `handleAddition` or `handleRemoval`
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   972
					if ( dit.changed ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   973
						dit.instance.trigger( 'change:' + dit.key, dit.instance, dit.related, options, true );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   974
						dit.changed = false;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   975
					}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   976
				});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   977
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   978
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   979
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   980
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   981
		 * When a model is added to a 'HasMany', trigger 'add' on 'this.instance' and notify reverse relations.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   982
		 * (should be 'HasOne', must set 'this.instance' as their related).
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   983
		*/
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   984
		handleAddition: function( model, coll, options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   985
			//console.debug('handleAddition called; args=%o', arguments);
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   986
			options = options ? _.clone( options ) : {};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   987
			this.changed = true;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   988
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   989
			_.each( this.getReverseRelations( model ), function( relation ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   990
				relation.addRelated( this.instance, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   991
			}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   992
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   993
			// Only trigger 'add' once the newly added model is initialized (so, has its relations set up)
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   994
			var dit = this;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   995
			!options.silent && Backbone.Relational.eventQueue.add( function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   996
				dit.instance.trigger( 'add:' + dit.key, model, dit.related, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   997
			});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   998
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
   999
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1000
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1001
		 * When a model is removed from a 'HasMany', trigger 'remove' on 'this.instance' and notify reverse relations.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1002
		 * (should be 'HasOne', which should be nullified)
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1003
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1004
		handleRemoval: function( model, coll, options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1005
			//console.debug('handleRemoval called; args=%o', arguments);
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1006
			options = options ? _.clone( options ) : {};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1007
			this.changed = true;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1008
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1009
			_.each( this.getReverseRelations( model ), function( relation ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1010
				relation.removeRelated( this.instance, null, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1011
			}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1012
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1013
			var dit = this;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1014
			!options.silent && Backbone.Relational.eventQueue.add( function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1015
				 dit.instance.trigger( 'remove:' + dit.key, model, dit.related, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1016
			});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1017
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1018
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1019
		handleReset: function( coll, options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1020
			var dit = this;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1021
			options = options ? _.clone( options ) : {};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1022
			!options.silent && Backbone.Relational.eventQueue.add( function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1023
				dit.instance.trigger( 'reset:' + dit.key, dit.related, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1024
			});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1025
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1026
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1027
		tryAddRelated: function( model, coll, options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1028
			var item = _.contains( this.keyIds, model.id );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1029
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1030
			if ( item ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1031
				this.addRelated( model, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1032
				this.keyIds = _.without( this.keyIds, model.id );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1033
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1034
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1035
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1036
		addRelated: function( model, options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1037
			// Allow 'model' to set up its relations before proceeding.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1038
			// (which can result in a call to 'addRelated' from a relation of 'model')
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1039
			var dit = this;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1040
			model.queue( function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1041
				if ( dit.related && !dit.related.get( model ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1042
					dit.related.add( model, _.defaults( { parse: false }, options ) );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1043
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1044
			});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1045
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1046
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1047
		removeRelated: function( model, coll, options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1048
			if ( this.related.get( model ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1049
				this.related.remove( model, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1050
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1051
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1052
	});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1053
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1054
	/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1055
	 * A type of Backbone.Model that also maintains relations to other models and collections.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1056
	 * New events when compared to the original:
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1057
	 *  - 'add:<key>' (model, related collection, options)
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1058
	 *  - 'remove:<key>' (model, related collection, options)
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1059
	 *  - 'change:<key>' (model, related model or collection, options)
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1060
	 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1061
	Backbone.RelationalModel = Backbone.Model.extend({
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1062
		relations: null, // Relation descriptions on the prototype
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1063
		_relations: null, // Relation instances
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1064
		_isInitialized: false,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1065
		_deferProcessing: false,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1066
		_queue: null,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1067
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1068
		subModelTypeAttribute: 'type',
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1069
		subModelTypes: null,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1070
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1071
		constructor: function( attributes, options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1072
			// Nasty hack, for cases like 'model.get( <HasMany key> ).add( item )'.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1073
			// Defer 'processQueue', so that when 'Relation.createModels' is used we trigger 'HasMany'
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1074
			// collection events only after the model is really fully set up.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1075
			// Example: event for "p.on( 'add:jobs' )" -> "p.get('jobs').add( { company: c.id, person: p.id } )".
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1076
			if ( options && options.collection ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1077
				var dit = this,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1078
					collection = this.collection =  options.collection;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1079
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1080
				// Prevent `collection` from cascading down to nested models; they shouldn't go into this `if` clause.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1081
				delete options.collection;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1082
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1083
				this._deferProcessing = true;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1084
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1085
				var processQueue = function( model ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1086
					if ( model === dit ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1087
						dit._deferProcessing = false;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1088
						dit.processQueue();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1089
						collection.off( 'relational:add', processQueue );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1090
					}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1091
				};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1092
				collection.on( 'relational:add', processQueue );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1093
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1094
				// So we do process the queue eventually, regardless of whether this model actually gets added to 'options.collection'.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1095
				_.defer( function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1096
					processQueue( dit );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1097
				});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1098
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1099
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1100
			Backbone.Relational.store.processOrphanRelations();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1101
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1102
			this._queue = new Backbone.BlockingQueue();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1103
			this._queue.block();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1104
			Backbone.Relational.eventQueue.block();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1105
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1106
			try {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1107
				Backbone.Model.apply( this, arguments );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1108
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1109
			finally {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1110
				// Try to run the global queue holding external events
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1111
				Backbone.Relational.eventQueue.unblock();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1112
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1113
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1114
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1115
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1116
		 * Override 'trigger' to queue 'change' and 'change:*' events
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1117
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1118
		trigger: function( eventName ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1119
			if ( eventName.length > 5 && eventName.indexOf( 'change' ) === 0 ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1120
				var dit = this,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1121
					args = arguments;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1122
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1123
				Backbone.Relational.eventQueue.add( function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1124
					if ( !dit._isInitialized ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1125
						return;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1126
					}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1127
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1128
					// Determine if the `change` event is still valid, now that all relations are populated
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1129
					var changed = true;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1130
					if ( eventName === 'change' ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1131
						changed = dit.hasChanged();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1132
					}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1133
					else {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1134
						var attr = eventName.slice( 7 ),
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1135
							rel = dit.getRelation( attr );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1136
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1137
						if ( rel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1138
							// If `attr` is a relation, `change:attr` get triggered from `Relation.onChange`.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1139
							// These take precedence over `change:attr` events triggered by `Model.set`.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1140
							// The relation set a fourth attribute to `true`. If this attribute is present,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1141
							// continue triggering this event; otherwise, it's from `Model.set` and should be stopped.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1142
							changed = ( args[ 4 ] === true );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1143
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1144
							// If this event was triggered by a relation, set the right value in `this.changed`
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1145
							// (a Collection or Model instead of raw data).
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1146
							if ( changed ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1147
								dit.changed[ attr ] = args[ 2 ];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1148
							}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1149
							// Otherwise, this event is from `Model.set`. If the relation doesn't report a change,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1150
							// remove attr from `dit.changed` so `hasChanged` doesn't take it into account.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1151
							else if ( !rel.changed ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1152
								delete dit.changed[ attr ];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1153
							}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1154
						}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1155
					}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1156
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1157
					changed && Backbone.Model.prototype.trigger.apply( dit, args );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1158
				});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1159
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1160
			else {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1161
				Backbone.Model.prototype.trigger.apply( this, arguments );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1162
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1163
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1164
			return this;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1165
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1166
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1167
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1168
		 * Initialize Relations present in this.relations; determine the type (HasOne/HasMany), then creates a new instance.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1169
		 * Invoked in the first call so 'set' (which is made from the Backbone.Model constructor).
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1170
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1171
		initializeRelations: function( options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1172
			this.acquire(); // Setting up relations often also involve calls to 'set', and we only want to enter this function once
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1173
			this._relations = {};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1174
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1175
			_.each( this.relations || [], function( rel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1176
				Backbone.Relational.store.initializeRelation( this, rel, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1177
			}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1178
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1179
			this._isInitialized = true;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1180
			this.release();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1181
			this.processQueue();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1182
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1183
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1184
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1185
		 * When new values are set, notify this model's relations (also if options.silent is set).
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1186
		 * (Relation.setRelated locks this model before calling 'set' on it to prevent loops)
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1187
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1188
		updateRelations: function( options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1189
			if ( this._isInitialized && !this.isLocked() ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1190
				_.each( this._relations, function( rel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1191
					// Update from data in `rel.keySource` if set, or `rel.key` otherwise
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1192
					var val = this.attributes[ rel.keySource ] || this.attributes[ rel.key ];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1193
					if ( rel.related !== val ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1194
						this.trigger( 'relational:change:' + rel.key, this, val, options || {} );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1195
					}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1196
				}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1197
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1198
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1199
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1200
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1201
		 * Either add to the queue (if we're not initialized yet), or execute right away.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1202
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1203
		queue: function( func ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1204
			this._queue.add( func );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1205
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1206
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1207
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1208
		 * Process _queue
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1209
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1210
		processQueue: function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1211
			if ( this._isInitialized && !this._deferProcessing && this._queue.isBlocked() ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1212
				this._queue.unblock();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1213
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1214
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1215
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1216
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1217
		 * Get a specific relation.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1218
		 * @param key {string} The relation key to look for.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1219
		 * @return {Backbone.Relation} An instance of 'Backbone.Relation', if a relation was found for 'key', or null.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1220
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1221
		getRelation: function( key ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1222
			return this._relations[ key ];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1223
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1224
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1225
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1226
		 * Get all of the created relations.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1227
		 * @return {Backbone.Relation[]}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1228
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1229
		getRelations: function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1230
			return _.values( this._relations );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1231
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1232
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1233
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1234
		 * Retrieve related objects.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1235
		 * @param key {string} The relation key to fetch models for.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1236
		 * @param [options] {Object} Options for 'Backbone.Model.fetch' and 'Backbone.sync'.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1237
		 * @param [refresh=false] {boolean} Fetch existing models from the server as well (in order to update them).
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1238
		 * @return {jQuery.when[]} An array of request objects
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1239
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1240
		fetchRelated: function( key, options, refresh ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1241
			// Set default `options` for fetch
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1242
			options = _.extend( { update: true, remove: false }, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1243
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1244
			var setUrl,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1245
				requests = [],
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1246
				rel = this.getRelation( key ),
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1247
				idsToFetch = rel && ( rel.keyIds || ( ( rel.keyId || rel.keyId === 0 ) ? [ rel.keyId ] : [] ) );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1248
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1249
			// On `refresh`, add the ids for current models in the relation to `idsToFetch`
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1250
			if ( refresh ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1251
				var models = rel.related instanceof Backbone.Collection ? rel.related.models : [ rel.related ];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1252
				_.each( models, function( model ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1253
					if ( model.id || model.id === 0 ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1254
						idsToFetch.push( model.id );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1255
					}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1256
				});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1257
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1258
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1259
			if ( idsToFetch && idsToFetch.length ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1260
				// Find (or create) a model for each one that is to be fetched
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1261
				var created = [],
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1262
					models = _.map( idsToFetch, function( id ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1263
						var model = Backbone.Relational.store.find( rel.relatedModel, id );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1264
						
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1265
						if ( !model ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1266
							var attrs = {};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1267
							attrs[ rel.relatedModel.prototype.idAttribute ] = id;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1268
							model = rel.relatedModel.findOrCreate( attrs, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1269
							created.push( model );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1270
						}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1271
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1272
						return model;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1273
					}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1274
				
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1275
				// Try if the 'collection' can provide a url to fetch a set of models in one request.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1276
				if ( rel.related instanceof Backbone.Collection && _.isFunction( rel.related.url ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1277
					setUrl = rel.related.url( models );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1278
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1279
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1280
				// An assumption is that when 'Backbone.Collection.url' is a function, it can handle building of set urls.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1281
				// To make sure it can, test if the url we got by supplying a list of models to fetch is different from
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1282
				// the one supplied for the default fetch action (without args to 'url').
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1283
				if ( setUrl && setUrl !== rel.related.url() ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1284
					var opts = _.defaults(
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1285
						{
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1286
							error: function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1287
								var args = arguments;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1288
								_.each( created, function( model ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1289
									model.trigger( 'destroy', model, model.collection, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1290
									options.error && options.error.apply( model, args );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1291
								});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1292
							},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1293
							url: setUrl
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1294
						},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1295
						options
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1296
					);
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1297
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1298
					requests = [ rel.related.fetch( opts ) ];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1299
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1300
				else {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1301
					requests = _.map( models, function( model ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1302
						var opts = _.defaults(
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1303
							{
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1304
								error: function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1305
									if ( _.contains( created, model ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1306
										model.trigger( 'destroy', model, model.collection, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1307
										options.error && options.error.apply( model, arguments );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1308
									}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1309
								}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1310
							},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1311
							options
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1312
						);
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1313
						return model.fetch( opts );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1314
					}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1315
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1316
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1317
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1318
			return requests;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1319
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1320
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1321
		get: function( attr ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1322
			var originalResult = Backbone.Model.prototype.get.call( this, attr );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1323
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1324
			// Use `originalResult` get if dotNotation not enabled or not required because no dot is in `attr`
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1325
			if ( !this.dotNotation || attr.indexOf( '.' ) === -1 ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1326
				return originalResult;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1327
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1328
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1329
			// Go through all splits and return the final result
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1330
			var splits = attr.split( '.' );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1331
			var result = _.reduce(splits, function( model, split ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1332
				if ( !( model instanceof Backbone.Model ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1333
					throw new Error( 'Attribute must be an instanceof Backbone.Model. Is: ' + model + ', currentSplit: ' + split );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1334
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1335
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1336
				return Backbone.Model.prototype.get.call( model, split );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1337
			}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1338
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1339
			if ( originalResult !== undefined && result !== undefined ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1340
				throw new Error( "Ambiguous result for '" + attr + "'. direct result: " + originalResult + ", dotNotation: " + result );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1341
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1342
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1343
			return originalResult || result;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1344
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1345
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1346
		set: function( key, value, options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1347
			Backbone.Relational.eventQueue.block();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1348
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1349
			// Duplicate backbone's behavior to allow separate key/value parameters, instead of a single 'attributes' object
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1350
			var attributes;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1351
			if ( _.isObject( key ) || key == null ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1352
				attributes = key;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1353
				options = value;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1354
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1355
			else {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1356
				attributes = {};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1357
				attributes[ key ] = value;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1358
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1359
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1360
			try {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1361
				var id = this.id,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1362
					newId = attributes && this.idAttribute in attributes && attributes[ this.idAttribute ];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1363
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1364
				// Check if we're not setting a duplicate id before actually calling `set`.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1365
				Backbone.Relational.store.checkId( this, newId );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1366
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1367
				var result = Backbone.Model.prototype.set.apply( this, arguments );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1368
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1369
				// Ideal place to set up relations, if this is the first time we're here for this model
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1370
				if ( !this._isInitialized && !this.isLocked() ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1371
					this.constructor.initializeModelHierarchy();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1372
					Backbone.Relational.store.register( this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1373
					this.initializeRelations( options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1374
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1375
				// The store should know about an `id` update asap
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1376
				else if ( newId && newId !== id ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1377
					Backbone.Relational.store.update( this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1378
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1379
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1380
				if ( attributes ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1381
					this.updateRelations( options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1382
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1383
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1384
			finally {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1385
				// Try to run the global queue holding external events
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1386
				Backbone.Relational.eventQueue.unblock();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1387
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1388
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1389
			return result;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1390
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1391
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1392
		unset: function( attribute, options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1393
			Backbone.Relational.eventQueue.block();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1394
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1395
			var result = Backbone.Model.prototype.unset.apply( this, arguments );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1396
			this.updateRelations( options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1397
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1398
			// Try to run the global queue holding external events
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1399
			Backbone.Relational.eventQueue.unblock();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1400
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1401
			return result;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1402
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1403
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1404
		clear: function( options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1405
			Backbone.Relational.eventQueue.block();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1406
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1407
			var result = Backbone.Model.prototype.clear.apply( this, arguments );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1408
			this.updateRelations( options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1409
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1410
			// Try to run the global queue holding external events
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1411
			Backbone.Relational.eventQueue.unblock();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1412
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1413
			return result;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1414
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1415
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1416
		clone: function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1417
			var attributes = _.clone( this.attributes );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1418
			if ( !_.isUndefined( attributes[ this.idAttribute ] ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1419
				attributes[ this.idAttribute ] = null;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1420
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1421
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1422
			_.each( this.getRelations(), function( rel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1423
				delete attributes[ rel.key ];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1424
			});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1425
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1426
			return new this.constructor( attributes );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1427
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1428
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1429
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1430
		 * Convert relations to JSON, omits them when required
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1431
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1432
		toJSON: function( options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1433
			// If this Model has already been fully serialized in this branch once, return to avoid loops
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1434
			if ( this.isLocked() ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1435
				return this.id;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1436
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1437
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1438
			this.acquire();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1439
			var json = Backbone.Model.prototype.toJSON.call( this, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1440
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1441
			if ( this.constructor._superModel && !( this.constructor._subModelTypeAttribute in json ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1442
				json[ this.constructor._subModelTypeAttribute ] = this.constructor._subModelTypeValue;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1443
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1444
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1445
			_.each( this._relations, function( rel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1446
				var related = json[ rel.key ],
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1447
					includeInJSON = rel.options.includeInJSON,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1448
					value = null;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1449
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1450
				if ( includeInJSON === true ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1451
					if ( related && _.isFunction( related.toJSON ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1452
						value = related.toJSON( options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1453
					}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1454
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1455
				else if ( _.isString( includeInJSON ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1456
					if ( related instanceof Backbone.Collection ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1457
						value = related.pluck( includeInJSON );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1458
					}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1459
					else if ( related instanceof Backbone.Model ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1460
						value = related.get( includeInJSON );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1461
					}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1462
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1463
					// Add ids for 'unfound' models if includeInJSON is equal to (only) the relatedModel's `idAttribute`
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1464
					if ( includeInJSON === rel.relatedModel.prototype.idAttribute ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1465
						if ( rel instanceof Backbone.HasMany ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1466
							value = value.concat( rel.keyIds );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1467
						}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1468
						else if  ( rel instanceof Backbone.HasOne ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1469
							value = value || rel.keyId;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1470
						}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1471
					}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1472
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1473
				else if ( _.isArray( includeInJSON ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1474
					if ( related instanceof Backbone.Collection ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1475
						value = [];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1476
						related.each( function( model ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1477
							var curJson = {};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1478
							_.each( includeInJSON, function( key ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1479
								curJson[ key ] = model.get( key );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1480
							});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1481
							value.push( curJson );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1482
						});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1483
					}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1484
					else if ( related instanceof Backbone.Model ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1485
						value = {};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1486
						_.each( includeInJSON, function( key ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1487
							value[ key ] = related.get( key );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1488
						});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1489
					}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1490
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1491
				else {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1492
					delete json[ rel.key ];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1493
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1494
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1495
				if ( includeInJSON ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1496
					json[ rel.keyDestination ] = value;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1497
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1498
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1499
				if ( rel.keyDestination !== rel.key ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1500
					delete json[ rel.key ];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1501
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1502
			});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1503
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1504
			this.release();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1505
			return json;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1506
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1507
	},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1508
	{
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1509
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1510
		 *
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1511
		 * @param superModel
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1512
		 * @returns {Backbone.RelationalModel.constructor}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1513
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1514
		setup: function( superModel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1515
			// We don't want to share a relations array with a parent, as this will cause problems with
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1516
			// reverse relations.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1517
			this.prototype.relations = ( this.prototype.relations || [] ).slice( 0 );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1518
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1519
			this._subModels = {};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1520
			this._superModel = null;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1521
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1522
			// If this model has 'subModelTypes' itself, remember them in the store
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1523
			if ( this.prototype.hasOwnProperty( 'subModelTypes' ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1524
				Backbone.Relational.store.addSubModels( this.prototype.subModelTypes, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1525
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1526
			// The 'subModelTypes' property should not be inherited, so reset it.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1527
			else {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1528
				this.prototype.subModelTypes = null;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1529
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1530
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1531
			// Initialize all reverseRelations that belong to this new model.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1532
			_.each( this.prototype.relations || [], function( rel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1533
				if ( !rel.model ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1534
					rel.model = this;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1535
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1536
				
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1537
				if ( rel.reverseRelation && rel.model === this ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1538
					var preInitialize = true;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1539
					if ( _.isString( rel.relatedModel ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1540
						/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1541
						 * The related model might not be defined for two reasons
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1542
						 *  1. it is related to itself
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1543
						 *  2. it never gets defined, e.g. a typo
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1544
						 *  3. the model hasn't been defined yet, but will be later
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1545
						 * In neither of these cases do we need to pre-initialize reverse relations.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1546
						 * However, for 3. (which is, to us, indistinguishable from 2.), we do need to attempt
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1547
						 * setting up this relation again later, in case the related model is defined later.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1548
						 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1549
						var relatedModel = Backbone.Relational.store.getObjectByName( rel.relatedModel );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1550
						preInitialize = relatedModel && ( relatedModel.prototype instanceof Backbone.RelationalModel );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1551
					}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1552
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1553
					if ( preInitialize ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1554
						Backbone.Relational.store.initializeRelation( null, rel );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1555
					}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1556
					else if ( _.isString( rel.relatedModel ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1557
						Backbone.Relational.store.addOrphanRelation( rel );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1558
					}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1559
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1560
			}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1561
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1562
			return this;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1563
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1564
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1565
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1566
		 * Create a 'Backbone.Model' instance based on 'attributes'.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1567
		 * @param {Object} attributes
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1568
		 * @param {Object} [options]
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1569
		 * @return {Backbone.Model}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1570
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1571
		build: function( attributes, options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1572
			var model = this;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1573
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1574
			// 'build' is a possible entrypoint; it's possible no model hierarchy has been determined yet.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1575
			this.initializeModelHierarchy();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1576
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1577
			// Determine what type of (sub)model should be built if applicable.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1578
			// Lookup the proper subModelType in 'this._subModels'.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1579
			if ( this._subModels && this.prototype.subModelTypeAttribute in attributes ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1580
				var subModelTypeAttribute = attributes[ this.prototype.subModelTypeAttribute ];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1581
				var subModelType = this._subModels[ subModelTypeAttribute ];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1582
				if ( subModelType ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1583
					model = subModelType;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1584
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1585
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1586
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1587
			return new model( attributes, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1588
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1589
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1590
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1591
		 *
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1592
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1593
		initializeModelHierarchy: function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1594
			// If we're here for the first time, try to determine if this modelType has a 'superModel'.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1595
			if ( _.isUndefined( this._superModel ) || _.isNull( this._superModel ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1596
				Backbone.Relational.store.setupSuperModel( this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1597
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1598
				// If a superModel has been found, copy relations from the _superModel if they haven't been
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1599
				// inherited automatically (due to a redefinition of 'relations').
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1600
				// Otherwise, make sure we don't get here again for this type by making '_superModel' false so we fail
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1601
				// the isUndefined/isNull check next time.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1602
				if ( this._superModel && this._superModel.prototype.relations ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1603
					// Find relations that exist on the `_superModel`, but not yet on this model.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1604
					var inheritedRelations = _.select( this._superModel.prototype.relations || [], function( superRel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1605
						return !_.any( this.prototype.relations || [], function( rel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1606
							return superRel.relatedModel === rel.relatedModel && superRel.key === rel.key;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1607
						}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1608
					}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1609
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1610
					this.prototype.relations = inheritedRelations.concat( this.prototype.relations );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1611
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1612
				else {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1613
					this._superModel = false;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1614
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1615
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1616
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1617
			// If we came here through 'build' for a model that has 'subModelTypes', and not all of them have been resolved yet, try to resolve each.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1618
			if ( this.prototype.subModelTypes && _.keys( this.prototype.subModelTypes ).length !== _.keys( this._subModels ).length ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1619
				_.each( this.prototype.subModelTypes || [], function( subModelTypeName ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1620
					var subModelType = Backbone.Relational.store.getObjectByName( subModelTypeName );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1621
					subModelType && subModelType.initializeModelHierarchy();
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1622
				});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1623
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1624
		},
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1625
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1626
		/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1627
		 * Find an instance of `this` type in 'Backbone.Relational.store'.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1628
		 * - If `attributes` is a string or a number, `findOrCreate` will just query the `store` and return a model if found.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1629
		 * - If `attributes` is an object and is found in the store, the model will be updated with `attributes` unless `options.update` is `false`.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1630
		 *   Otherwise, a new model is created with `attributes` (unless `options.create` is explicitly set to `false`).
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1631
		 * @param {Object|String|Number} attributes Either a model's id, or the attributes used to create or update a model.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1632
		 * @param {Object} [options]
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1633
		 * @param {Boolean} [options.create=true]
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1634
		 * @param {Boolean} [options.merge=true]
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1635
		 * @param {Boolean} [options.parse=false]
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1636
		 * @return {Backbone.RelationalModel}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1637
		 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1638
		findOrCreate: function( attributes, options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1639
			options || ( options = {} );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1640
			var parsedAttributes = ( _.isObject( attributes ) && options.parse && this.prototype.parse ) ?
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1641
				this.prototype.parse( attributes ) : attributes;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1642
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1643
			// Try to find an instance of 'this' model type in the store
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1644
			var model = Backbone.Relational.store.find( this, parsedAttributes );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1645
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1646
			// If we found an instance, update it with the data in 'item' (unless 'options.merge' is false).
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1647
			// If not, create an instance (unless 'options.create' is false).
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1648
			if ( _.isObject( attributes ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1649
				if ( model && options.merge !== false ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1650
					// Make sure `options.collection` doesn't cascade to nested models
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1651
					delete options.collection;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1652
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1653
					model.set( parsedAttributes, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1654
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1655
				else if ( !model && options.create !== false ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1656
					model = this.build( attributes, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1657
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1658
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1659
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1660
			return model;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1661
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1662
	});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1663
	_.extend( Backbone.RelationalModel.prototype, Backbone.Semaphore );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1664
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1665
	/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1666
	 * Override Backbone.Collection._prepareModel, so objects will be built using the correct type
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1667
	 * if the collection.model has subModels.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1668
	 * Attempts to find a model for `attrs` in Backbone.store through `findOrCreate`
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1669
	 * (which sets the new properties on it if found), or instantiates a new model.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1670
	 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1671
	Backbone.Collection.prototype.__prepareModel = Backbone.Collection.prototype._prepareModel;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1672
	Backbone.Collection.prototype._prepareModel = function ( attrs, options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1673
		var model;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1674
		
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1675
		if ( attrs instanceof Backbone.Model ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1676
			if ( !attrs.collection ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1677
				attrs.collection = this;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1678
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1679
			model = attrs;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1680
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1681
		else {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1682
			options || ( options = {} );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1683
			options.collection = this;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1684
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1685
			if ( typeof this.model.findOrCreate !== 'undefined' ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1686
				model = this.model.findOrCreate( attrs, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1687
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1688
			else {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1689
				model = new this.model( attrs, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1690
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1691
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1692
			if ( model && model.isNew() && !model._validate( attrs, options ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1693
				this.trigger( 'invalid', this, attrs, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1694
				model = false;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1695
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1696
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1697
		
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1698
		return model;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1699
	};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1700
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1701
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1702
	/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1703
	 * Override Backbone.Collection.set, so we'll create objects from attributes where required,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1704
	 * and update the existing models. Also, trigger 'relational:add'.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1705
	 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1706
	var set = Backbone.Collection.prototype.__set = Backbone.Collection.prototype.set;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1707
	Backbone.Collection.prototype.set = function( models, options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1708
		// Short-circuit if this Collection doesn't hold RelationalModels
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1709
		if ( !( this.model.prototype instanceof Backbone.RelationalModel ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1710
			return set.apply( this, arguments );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1711
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1712
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1713
		if ( options && options.parse ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1714
			models = this.parse( models, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1715
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1716
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1717
		if ( !_.isArray( models ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1718
			models = models ? [ models ] : [];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1719
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1720
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1721
		var newModels = [],
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1722
			toAdd = [];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1723
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1724
		//console.debug( 'calling add on coll=%o; model=%o, options=%o', this, models, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1725
		_.each( models, function( model ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1726
			if ( !( model instanceof Backbone.Model ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1727
				model = Backbone.Collection.prototype._prepareModel.call( this, model, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1728
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1729
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1730
			if ( model ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1731
				toAdd.push( model );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1732
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1733
				if ( !( this.get( model ) || this.get( model.cid ) ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1734
					newModels.push( model );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1735
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1736
				// If we arrive in `add` while performing a `set` (after a create, so the model gains an `id`),
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1737
				// we may get here before `_onModelEvent` has had the chance to update `_byId`.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1738
				else if ( model.id != null ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1739
					this._byId[ model.id ] = model;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1740
				}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1741
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1742
		}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1743
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1744
		// Add 'models' in a single batch, so the original add will only be called once (and thus 'sort', etc).
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1745
		// If `parse` was specified, the collection and contained models have been parsed now.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1746
		set.call( this, toAdd, _.defaults( { parse: false }, options ) );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1747
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1748
		_.each( newModels, function( model ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1749
			// Fire a `relational:add` event for any model in `newModels` that has actually been added to the collection.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1750
			if ( this.get( model ) || this.get( model.cid ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1751
				this.trigger( 'relational:add', model, this, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1752
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1753
		}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1754
		
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1755
		return this;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1756
	};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1757
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1758
	/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1759
	 * Override 'Backbone.Collection.remove' to trigger 'relational:remove'.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1760
	 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1761
	var remove = Backbone.Collection.prototype.__remove = Backbone.Collection.prototype.remove;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1762
	Backbone.Collection.prototype.remove = function( models, options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1763
		// Short-circuit if this Collection doesn't hold RelationalModels
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1764
		if ( !( this.model.prototype instanceof Backbone.RelationalModel ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1765
			return remove.apply( this, arguments );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1766
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1767
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1768
		models = _.isArray( models ) ? models.slice() : [ models ];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1769
		options || ( options = {} );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1770
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1771
		var toRemove = [];
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1772
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1773
		//console.debug('calling remove on coll=%o; models=%o, options=%o', this, models, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1774
		_.each( models, function( model ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1775
			model = this.get( model ) || this.get( model.cid );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1776
			model && toRemove.push( model );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1777
		}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1778
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1779
		if ( toRemove.length ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1780
			remove.call( this, toRemove, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1781
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1782
			_.each( toRemove, function( model ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1783
				this.trigger('relational:remove', model, this, options);
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1784
			}, this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1785
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1786
		
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1787
		return this;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1788
	};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1789
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1790
	/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1791
	 * Override 'Backbone.Collection.reset' to trigger 'relational:reset'.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1792
	 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1793
	var reset = Backbone.Collection.prototype.__reset = Backbone.Collection.prototype.reset;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1794
	Backbone.Collection.prototype.reset = function( models, options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1795
		options = _.extend( { merge: true }, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1796
		reset.call( this, models, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1797
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1798
		if ( this.model.prototype instanceof Backbone.RelationalModel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1799
			this.trigger( 'relational:reset', this, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1800
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1801
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1802
		return this;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1803
	};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1804
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1805
	/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1806
	 * Override 'Backbone.Collection.sort' to trigger 'relational:reset'.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1807
	 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1808
	var sort = Backbone.Collection.prototype.__sort = Backbone.Collection.prototype.sort;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1809
	Backbone.Collection.prototype.sort = function( options ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1810
		sort.call( this, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1811
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1812
		if ( this.model.prototype instanceof Backbone.RelationalModel ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1813
			this.trigger( 'relational:reset', this, options );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1814
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1815
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1816
		return this;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1817
	};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1818
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1819
	/**
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1820
	 * Override 'Backbone.Collection.trigger' so 'add', 'remove' and 'reset' events are queued until relations
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1821
	 * are ready.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1822
	 */
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1823
	var trigger = Backbone.Collection.prototype.__trigger = Backbone.Collection.prototype.trigger;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1824
	Backbone.Collection.prototype.trigger = function( eventName ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1825
		// Short-circuit if this Collection doesn't hold RelationalModels
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1826
		if ( !( this.model.prototype instanceof Backbone.RelationalModel ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1827
			return trigger.apply( this, arguments );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1828
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1829
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1830
		if ( eventName === 'add' || eventName === 'remove' || eventName === 'reset' ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1831
			var dit = this,
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1832
				args = arguments;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1833
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1834
			if ( _.isObject( args[ 3 ] ) ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1835
				args = _.toArray( args );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1836
				// the fourth argument is the option object.
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1837
				// we need to clone it, as it could be modified while we wait on the eventQueue to be unblocked
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1838
				args[ 3 ] = _.clone( args[ 3 ] );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1839
			}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1840
			
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1841
			Backbone.Relational.eventQueue.add( function() {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1842
				trigger.apply( dit, args );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1843
			});
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1844
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1845
		else {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1846
			trigger.apply( this, arguments );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1847
		}
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1848
		
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1849
		return this;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1850
	};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1851
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1852
	// Override .extend() to automatically call .setup()
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1853
	Backbone.RelationalModel.extend = function( protoProps, classProps ) {
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1854
		var child = Backbone.Model.extend.apply( this, arguments );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1855
		
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1856
		child.setup( this );
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1857
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1858
		return child;
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1859
	};
815589aed866 django app renkamanager (models, vanilla views, utils, static files)
cavaliet
parents:
diff changeset
  1860
})();