-
Notifications
You must be signed in to change notification settings - Fork 87
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
111 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
{ | ||
"name": "angular-restmod", | ||
"version": "0.13.0", | ||
"version": "0.14.0", | ||
"authors": [ | ||
"Ignacio Baixas <[email protected]>" | ||
], | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
/** | ||
* API Bound Models for AngularJS | ||
* @version v0.13.0 - 2014-03-14 | ||
* @version v0.14.0 - 2014-05-19 | ||
* @link https://github.com/angular-platanus/restmod | ||
* @author Ignacio Baixas <[email protected]> | ||
* @license MIT License, http://www.opensource.org/licenses/MIT | ||
|
@@ -443,7 +443,7 @@ angular.module('plRestmod').provider('$restmod', function() { | |
/** | ||
* @memberof Model | ||
* | ||
* @description Returns a model's object private key from model decoded data. | ||
* @description Returns a model's object private key from model raw data. | ||
* If data is not an object, then it is considered to be the primary key value. | ||
* | ||
* The private key is the passed to the $urlFor function to obtain an object's url. | ||
|
@@ -454,9 +454,9 @@ angular.module('plRestmod').provider('$restmod', function() { | |
* @param {object} _data decoded object data (or pk) | ||
* @return {mixed} object private key | ||
*/ | ||
Model.$inferKey = function(_data) { | ||
if(!_data || typeof _data[primaryKey] === 'undefined') return null; | ||
return _data[primaryKey]; | ||
Model.$inferKey = function(_rawData) { | ||
if(!_rawData || typeof _rawData[primaryKey] === 'undefined') return null; | ||
return _rawData[primaryKey]; | ||
}; | ||
|
||
/** Runtime modifiers - private api for now */ | ||
|
@@ -543,14 +543,14 @@ angular.module('plRestmod').provider('$restmod', function() { | |
/** | ||
* @memberof Model# | ||
* | ||
* @description Copyies another object's properties. | ||
* @description Copyies another object's non-private properties. | ||
* | ||
* @param {object} _other Object to merge. | ||
* @return {Model} self | ||
*/ | ||
$extend: function(_other) { | ||
for(var tmp in _other) { | ||
if (_other.hasOwnProperty(tmp)) { | ||
if (_other.hasOwnProperty(tmp) && tmp[0] !== '$') { | ||
this[tmp] = _other[tmp]; | ||
} | ||
} | ||
|
@@ -674,7 +674,7 @@ angular.module('plRestmod').provider('$restmod', function() { | |
*/ | ||
$decode: function(_raw, _mask) { | ||
transform(_raw, this, '', _mask || READ_MASK, true, this); | ||
if(!this.$pk) this.$pk = Model.$inferKey(this); // TODO: improve this, warn if key changes | ||
if(!this.$pk) this.$pk = Model.$inferKey(_raw); // TODO: warn if key changes | ||
callback('after-feed', this, _raw); | ||
return this; | ||
}, | ||
|
@@ -728,6 +728,8 @@ angular.module('plRestmod').provider('$restmod', function() { | |
* | ||
* @description Begin a server request to create/update resource. | ||
* | ||
* If resource is new and it belongs to a collection and it hasnt been revealed, then it will be revealed. | ||
* | ||
* The request's promise is provided as the $promise property. | ||
* | ||
* @return {Model} this | ||
|
@@ -760,6 +762,12 @@ angular.module('plRestmod').provider('$restmod', function() { | |
return this.$send(request, function(_response) { | ||
var data = _response.data; | ||
if (data && !isArray(data)) this.$decode(data); | ||
|
||
// reveal item (if not yet positioned) | ||
if(this.$scope.$isCollection && this.$position === undefined && !this.$preventReveal) { | ||
this.$scope.$add(this, this.$revealAt); | ||
} | ||
|
||
callback('after-create', this, _response); | ||
callback('after-save', this, _response); | ||
}, function(_response) { | ||
|
@@ -794,6 +802,50 @@ angular.module('plRestmod').provider('$restmod', function() { | |
}, function(_response) { | ||
callback('after-destroy-error', this, _response); | ||
}); | ||
}, | ||
|
||
// Collection related methods. | ||
|
||
/** | ||
* @memberof Model# | ||
* | ||
* @description Changes the location of the object in the bound collection. | ||
* | ||
* If object hasn't been revealed, then this method will change the index where object will be revealed at. | ||
* | ||
* @param {integer} _to New object position (index) | ||
* @return {Model} this | ||
*/ | ||
$moveTo: function(_to) { | ||
if(this.$position !== undefined) { | ||
// TODO: move item to given index. | ||
// TODO: callback | ||
} else { | ||
this.$revealAt = _to; | ||
} | ||
return this; | ||
}, | ||
|
||
/** | ||
* @memberof Model# | ||
* | ||
* @description Reveal in collection | ||
* | ||
* If instance is bound to a collection and it hasnt been revealed (because it's new and hasn't been saved), | ||
* then calling this method without parameters will force the object to be added to the collection. | ||
* | ||
* If this method is called with **_show** set to `false`, then the object wont be revealed by a save operation. | ||
* | ||
* @param {boolean} _show Whether to reveal inmediatelly or prevent automatic reveal. | ||
* @return {Model} this | ||
*/ | ||
$reveal: function(_show) { | ||
if(_show === undefined || _show) { | ||
this.$scope.$add(this, this.$revealAt); | ||
} else { | ||
this.$preventReveal = true; | ||
} | ||
return this; | ||
} | ||
}; | ||
|
||
|
@@ -866,61 +918,42 @@ angular.module('plRestmod').provider('$restmod', function() { | |
/** | ||
* @memberof ModelCollection# | ||
* | ||
* @description Loads a new model instance bound to this context and a given pk. | ||
* | ||
* ATENTION: this method does not adds the new object to the collection, it is intended to be a base | ||
* building method that can be overriden to provide special caching logics. | ||
* @description Builds a new instance of this model, bound to this instance scope, sets its primary key. | ||
* | ||
* @param {mixed} _pk object private key | ||
* @return {Model} New model instance | ||
*/ | ||
$load: function(_pk) { | ||
$new: function(_pk) { | ||
return new Model(this, _pk); | ||
}, | ||
|
||
/** | ||
* @memberof ModelCollection# | ||
* | ||
* @description Builds a new instance of this model, sets its primary key. | ||
* | ||
* @param {mixed} _pk object private key | ||
* @return {Model} New model instance | ||
*/ | ||
$new: function(_pk) { | ||
var obj = this.$load(_pk); | ||
if(this.$isCollection) this.$add(obj); | ||
return obj; | ||
}, | ||
|
||
/** | ||
* @memberof ModelCollection# | ||
* @description Builds a new instance of this model, does not assign a pk to the created object. | ||
* | ||
* @description Builds a new instance of this model | ||
* ATTENTION: item will not show in collection until `$save` is called. To reveal item before than call `$reveal`. | ||
* | ||
* @param {object} _init Initial values | ||
* @return {Model} model instance | ||
*/ | ||
$build: function(_init) { | ||
var obj = this.$load(Model.$inferKey(_init)); | ||
angular.extend(obj, _init); | ||
|
||
if(this.$isCollection) this.$add(obj); | ||
return obj; | ||
return this.$new().$extend(_init); | ||
}, | ||
|
||
/** | ||
* @memberof ModelCollection# | ||
* | ||
* @description Builds a new instance of this model using undecoded data | ||
* @description Builds a new instance of this model using undecoded data. | ||
* | ||
* ATTENTION: does not automatically reveal item in collection, chain a call to $reveal to do so. | ||
* | ||
* @param {object} _raw Undecoded data | ||
* @return {Model} model instance | ||
*/ | ||
$buildRaw: function(_raw) { | ||
var obj = this.$load(Model.$inferKey(_raw)); // TODO: using infer key on raw... | ||
var obj = this.$new(Model.$inferKey(_raw)); | ||
obj.$decode(_raw); | ||
|
||
if(this.$isCollection) this.$add(obj); | ||
return obj; | ||
}, | ||
|
||
|
@@ -933,7 +966,7 @@ angular.module('plRestmod').provider('$restmod', function() { | |
* @return {Model} model instance | ||
*/ | ||
$find: function(_pk) { | ||
return this.$load(_pk).$fetch(); | ||
return this.$new(_pk).$fetch(); | ||
}, | ||
|
||
/** | ||
|
@@ -1049,7 +1082,9 @@ angular.module('plRestmod').provider('$restmod', function() { | |
$feed: function(_raw) { | ||
if(!this.$isCollection) throw new Error('$feed is only supported by collections'); | ||
if(!this.$resolved) this.length = 0; // reset contents if not resolved. | ||
forEach(_raw, this.$buildRaw, this); | ||
for(var i = 0, l = _raw.length; i < l; i++) { | ||
this.$buildRaw(_raw[i]).$reveal(); // build and disclose every item. | ||
} | ||
this.$resolved = true; | ||
return this; | ||
}, | ||
|
@@ -1131,12 +1166,13 @@ angular.module('plRestmod').provider('$restmod', function() { | |
*/ | ||
$add: function(_obj, _idx) { | ||
// TODO: make sure object is f type Model? | ||
if(this.$isCollection) { | ||
if(typeof _idx !== 'undefined') { | ||
if(this.$isCollection && _obj.$position === undefined) { | ||
if(_idx !== undefined) { | ||
this.splice(_idx, 0, _obj); | ||
} else { | ||
this.push(_obj); | ||
} | ||
_obj.$position = true; // use true for now, keeping position updated can be expensive | ||
callback('after-add', this, _obj); | ||
} | ||
return this; | ||
|
@@ -1159,6 +1195,7 @@ angular.module('plRestmod').provider('$restmod', function() { | |
var idx = this.$indexOf(_obj); | ||
if(idx !== -1) { | ||
this.splice(idx, 1); | ||
_obj.$position = undefined; | ||
callback('after-remove', this, _obj); | ||
} | ||
return this; | ||
|
@@ -1284,6 +1321,8 @@ angular.module('plRestmod').provider('$restmod', function() { | |
* | ||
* Primary keys are passed to scope's url methods to generate urls. The default primary key is 'id'. | ||
* | ||
* **ATTENTION** Primary keys are extracted from raw data, so _key must use raw api naming. | ||
* | ||
* @param {string|function} _key New primary key. | ||
* @return {ModelBuilder} self | ||
*/ | ||
|
@@ -1689,7 +1728,7 @@ angular.module('plRestmod').provider('$restmod', function() { | |
// only reload object if id changes | ||
if(_inline) | ||
{ | ||
if(!this[_attr] || this[_attr].$pk !== _model.$inferKey(_raw)) { // TODO: using infer key on raw... | ||
if(!this[_attr] || this[_attr].$pk !== _model.$inferKey(_raw)) { | ||
this[_attr] = _model.$buildRaw(_raw); | ||
} else { | ||
this[_attr].$decode(_raw); | ||
|
@@ -1698,7 +1737,7 @@ angular.module('plRestmod').provider('$restmod', function() { | |
else | ||
{ | ||
if(!this[_attr] || this[_attr].$pk !== _raw) { | ||
this[_attr] = _model.$load(_raw); // use $new instead of $build | ||
this[_attr] = _model.$new(_raw); // use $new instead of $build | ||
if(_prefetch) { | ||
this[_attr].$fetch(); | ||
} | ||
|
Oops, something went wrong.