angular-restmod
angular-restmod copied to clipboard
Add CachedModel plugin
The cached model plugin should be able to resolve by id or url objects that have already been fetched.
Some sort of caching would be great. Is this the plugin you are referring to porting? https://github.com/scosman/Backbone.CachedModel/blob/master/BackboneLocalCache.js
Not sure if the Backbone api will match $restmod's, but is probable a good starting point for this, specially for stuff related to integration with local storage.
Basically this is how I think the plugin should work:
- Override the
ScopeApi.$find
method to look in cache before attempting to fetch from server. - Hook to the
after-fetch
event to store serialized items in cache every time server returns them.
Some doubts:
- How to handle cached collections?
- Do we need to generate local temporary keys like backbone does?
@iobaixas off topic but how do you define custom url's? For example how ng-resource allows you to override a specific method with a custom url. Typically all my URLs fall into restful spec but sometimes i have custom fn's or slightly different urls than others.
You can give a single resource instance a different url by building it using the $single
method:
var myModelInst = MyModel.$single('/api/wharever');
If you need to change the url for one of the RESTful actions, then it depends on the action.
- for GET you should implement the $fetchUrlFor instance method or override the $url() instance method.
- for UPDATE you should implement the $updateUrlFor instance method or override the $url() instance method.
- for DELETE you should implement the $destroyUrlFor instance method or override the $url() instance method.
- for CREATE you should implement the $createUrlFor instance method.
If you are talking about custom actions, then you would need to call $send and build the request yourself, like this:
$restmod.model('/api/restful', {
notVeryRestful: function() {
return this.$send({
url: this.$url() + '/unrestfulAction',
method: 'POST'
}).$then(function() {
// maybe do something with request response...
));
}
});
Hope that helps!
Back on the topic of caching, ngResource has caching built in:
cache – {boolean|Cache} – If true, a default $http cache will be used to cache the GET request, otherwise if a cache instance built with $cacheFactory, this cache will be used for caching.
wonder if its easy just to hook into that?
@iobaixas What about if my request is 'restful' but doesn't adhere quite to your spec. For example:
findOne: function(formId, id){
return $http.get('api/group/' + formId + '/' + id);
}
is there anyway to format the url dynamically like that?
@iobaixas Here is my first cut of it ... Would LOVE feedback ... https://gist.github.com/amcdnl/f14cbfc3738668457ebb
@iobaixas on the notVeryRestful: function() {
how would you send it data? I was looking at $encode but it infers the data from the instance. Just JSON.stringify()
?
@iobaixas sorry for all the spam but how could you add a method to the 'class'? You could do something like:
var model = $restmod.model('api/account');
model.setPassword = function(val) {
return this.$send({
url: this.$url() + '/setpassword',
method: 'POST',
data: JSON.stringify(val)
});
};
but thats not very 'pretty'. In the past, I've used a pattern where you could pass the 'static' properties on the 'class' as another object. For instance:
var model = $restmod.model('api/account', { ..Static.. }, { ..Prototype.. });
Thoughts?
You don't need to JSON.stringify
$http will handle that for you.
To add a method to a class use '@' at the model definition object:
$restmod.model('url', {
'@myClassMethod': function() { /* do something */ }
});
Actually that will add the method both to the class and to the model collections.
@amcdnl, about the custom url, you could always override the $url method. Maybe the findOne
example if better handled by a hasMany relation?
@iobaixas I updated the gist w/ some updates.
re hasMany: The hasMany would be interesting. Its mainly just a qualifier for my models. Maybe I should reconsider that api.
re stringify: Thats perfect!
@iobaixas 2 more questions ... sorry ...
-
If I have a model that only returns 1 thing, how do I use restmod to return that? For example:
api/settings
only returns a object ( has update/delete though). It accepts no params, etc. $find / $search don't seem to be the fit for this. It seems like$single
might be the right fit but unsure how to use it. -
If I use the
@myClassMethod
the$send
function is unavailable. Example:
'@loginBanner': function(){
return this.$send({
url: this.$url() + '/login-banner',
method: 'GET'
});
}
- You should use $single:
var oneRecord = Settings.$single('api/settings').$fetch()
(fetch is optional). - Thats weird, could you copy here the entire code you are using when defining the model?
The single is a bit odd ... I ended up with something like this ....
module.factory('SettingsModel', function($restmod){
var model = $restmod.model('api/settings', {
"@get": function(){
return this.$single(this.$url()).$fetch();
},
"@loginBanner": function(){
return this.$send({
url: this.$url() + '/login-banner',
method: 'GET'
});
}
});
return model;
});
and Im using it in a route resolve like:
$stateProvider.state('settings', {
url: '/settings',
templateUrl: 'app/admin/settings/settings.tpl.html',
controller: 'SettingsCtrl',
resolve: {
settings: function(SettingsModel) {
return SettingsModel.get();
}
}
});
I ended up making it quite a bit simpler ... reason being I needed pointers ( not just cache ) of the items. Any thoughts? https://gist.github.com/amcdnl/f14cbfc3738668457ebb
You should have a way to invalidate the cache as well, or parts of the cache.
@iobaixas Above you mention a $send example, that works for 'singles' but not 'collections'. How would I implement something like this for collections
"@$searchLight": function(){
return this.$send({
url: this.$url() + '/light',
method: 'GET'
}).$promise;
}
P.S. - I updated my gist to reduce more code, take a gander when you get a sec.https://gist.github.com/amcdnl/f14cbfc3738668457ebb . The only problem is it returns promises ( yours doesn't ) by default and doesn't delete them.
Interesting plugin I ran across today: https://github.com/ClouDesire/angular-browser-cache-manager
This is interesting: https://github.com/VasilioRuzanni/angular-modelizer and they have cache built in
I am also very interested in a caching mechanism. Are there any current plans to integrate this into restmod?
For now, I have built a simple CacheModel mixin, which is based on the gist by @amcdnl and the corresponding pull request: cachemod. Though, it stills needs to handle updates and deletes. Would this generally be the right approach?
Who would be interested to work on this with me?
Maybe I'm missing something, and not purposefully trying to step on toes, but this should be trivial. Provided there is some sort of UoW implemented.