Ho to avoid the append of an id or additional parameters by backbone?
For example, if I'd like call the following url:
https://www.gogle.de
backbone sends out this url:
https://www.gogle.de/?_=1377848245402
How can I stop backbone adding an id to my url?
It's not a problem caused by Backbone. I deactivated the ajax_caching, after activating it, the ids were gone :)
$.ajaxSetup ({
// Disable caching of AJAX responses */
cache: true
});
Related
I have used cache:false in my state to avoid templates(html view) caching like below.
.state('index.project_setup', {
url: '/:customerTag/project-setup',
templateUrl: 'app/views/common/customer/projects/setup_projects_wizard.html',
data: { pageTitle: 'Project Setup' },
cache: false
})
After applying changes in to html file, sometimes i need to hard refresh the page instead of just reload. So is it something i am missing or is there any way to accomplish this thing?
There is a difference between Angular template caching and your browser caching.
When Angular loads a template for the first time, it will fire an AJAX request for that template, and then store the HTMLin a service called $templateCache, so if the exact same template is required again, it will skip the AJAX call and will use the HTML stored in $templateCache.
Once you refreshed your page, the $templateCache service is initialized (because all the JS is initialized) and all the cached HTMLs are gone, so again when Angular will require an HTML file for a template, it will fire AJAX call the first time, store it in the $templateCache and then will use the cached HTML from here on out.
Your browser on the other hand, does not "initialize" his cache on every refresh, so if you will request a file that was cached before, the browser will skip the HTTP call and will use his cached version if one is available.
So lets say we need template named x.html, what will happen is the following pseudo code:
if (x.html exists in $templateCache)
return x.html from $templateCache
else
AngularJS perform HTTP GET for x.html
if (browser has x.html cached version)
return x.html from browser cache and don't fire HTTP request
else
fire HTTP request for x.html and return the result
That is way you must "hard reload" your templates every once in a while.
My solution for development, is attaching a changing query string to the template URL, for example:
.state('index.project_setup', {
url: '/:customerTag/project-setup',
templateUrl: 'app/views/common/customer/projects/setup_projects_wizard.html?v=' + Date.now(),
data: { pageTitle: 'Project Setup' },
cache: false
})
That is a simple trick that causes the browser to always fetch the HTML file because the query string is never the same (well, it will be the same for 1 millisecond :)), so every time the browser will get an HTTP request for that HTML, it will not match previous requests and will not use the cache.
How can I pass data to my angular project using external redirects?
I need to pass mdToast messages to my project from an external source. I need to intercept these messages at all the controllers. Currently, I am using query strings to achieve this right now. How can I intercept this query string in the runBlock? I want to somehow intercept it at all routes.
Here's how I am sending the query string:
$stateProvider
.state('toastIntercept', {
url: '/toastIntercept?message',
templateUrl: 'views/redirect-by-intercept.html',
controller: 'redirectController'
});
On further note, here's what I am actually trying to do:
I understand discussions are discouraged here but I'd really appreciate some inputs or some resources or articles on this. I haven't been able to find any credible ones.
I generate emails to my users using node. Users can take some actions through that email but ultimately land on my static angular project. What would be the right way to achieve this?
I can think of two possible ways:
Using a Proxy that handles the email redirection, performs the actions and redirects to the angular project using a toast message as a query string to notify the user about his action.
Instead of the Proxy, handle the email redirects on my static angular project itself using one of the routes. This however feels like an anti-pattern to me since a static project shouldn't be handling API level tasks.
If I understand you correctly, I think you could solve this problem by adding an interceptor.
.config(function($httpProvider) {
//Register the interceptor via an anonymous factory
$httpProvider.interceptors.push(function($q, dependency1, dependency2) {
return {
'request': function(config) {
// same as above
},
'response': function(response) {
// same as above
}
};
});
});
Yo could add interceptos for both requests and reponses.
Other possible values for the interceptos are: 'requestError' and 'responseError'
You could Also define a factory and then do the following
$httpProvider.interceptors.push('connectionFactoryInterceptor');
What is a good pattern for updating angular data from a ngResource service that has been cached?
I been trawling posts like this one [1]: How to refresh / invalidate $resource cache in AngularJS, but would be good to hear from angular experts on the right approach for this specific (but pretty general) scenario.
I am looking for a general pattern here. Both in understanding and in implementing angular - I am a novice at it.
I have a pretty standard ngResource service that has a very standard query method, and a custom put method update.
myServices.factory('ThingsService', [
'$resource',
function ($resource) {
return $resource('/api/things/:id', { id: '#id' }, {
query: { method: 'GET', isArray: true, cache: true },
update: {method: 'PUT', cache: true },
});
}]);
I am using it from a controller like this:
$scope.things = ThingsService.query(function (x) {
// must assign these only once data is loaded
$scope.allCount = x.Things.length;
$scope.incomingCount = $filter('filter')(x.Things, { State: 'incoming' }).length;
});
So far so good. The data is returned just fine, and it renders nicely in a dashboard view.
We support in-place-editing and the user can edit the data right there in the dashboard list.
First take a shadow copy of the thing using angular.copy(...) so that we can support buffering of the changes for the user. (just like a dialog box does for a user). Then when they confirm their changes, we call with the shadow copy:
ThingsService.update({ id: currentThing.Id }, { Data: currentThing.Data }, function () {
//TODO: now, if this PUT succeeds,
//I want to update the value of $scope.things array to reflect the changes,
//without going to back to the server for the whole array.
});
This correctly PUTS the changes to the server, which returns an updated thing, but the dashboard view which is bound to the query method is not updated auto-magically. Was kind of hoping angular and the ThingsService and its cache would take care of that for me somehow, you know by updating the cached data. Since the service should know that I just updated one of the items that the service serves up.
So to avoid going all the way back to the server we have told the ThingsService to cache its results, which is a good start. But how are you supposed to update the changed thing in the cached data?
Is there a standard pattern for this kind of update with a ngResource service?
Preferably I wouldn't have to mess with the cache directly. I should not even care that it is cached or how. I just want $scope.things to reflect the posted changes changes.
I'm starting to implement backbone.js on a new app, however, the API I'm using it is not kind of restful, so I want to know if I can still use some similar methods, for sample:
Let's say I have a trivial scenario where I need among other options to delete users, however each option has its own controller, so I trigger them like this:
fetch : FetchController.php
Update : DeleteController.php?data={'id':'x'}
So my view would look like this:
var UserEditView = Backbone.View.extend({
events: {
'submit .delete-form': 'deleteUser'
},
//.... other methods
deleteUser: function(event) {
//user is a instance of my User Collection
this.user.destroy({
//here is where I point my question
});
}
});
Let's say all my controllers are called via Post Method, so I don't have the change to send a Delete Method to destroy... my question is, can I create a own destroy method? or at least configure it to call an custom controller? so I can do the same to create and edit records?
Any help would be really appreciated.
Thanks in advance.
You should definitely use $.ajax options override it with attributes url, method and data
model.fetch({
url: 'FetchController.php'
});
model.destroy({
url: 'DeleteController.php',
method: 'POST',
data: "id=x"
});
You may also override fetch and destroy method inside your model to do not use this every time in views.
Or even override Backbone.sync method to support your backend services. Here is a link to related question.
I use Rails 4 + backbone in my application.
Everything is good. New model is created in backbone and saved by calling:
newItem.save(null, {success: this.sendSuccess, error: this.sendError});
However, implementing a new feature I need to change one of the model attributes. What I see that a PUT action is fired just before sendSuccess is called, which I want to avoid.
Moreover, the url is very strange. Save action calls this url:
Remote Address:127.0.0.1:3000
Request URL:http://www.lvh.me:3000/api/user/1/tickets
Request Method:POST
and then, after server return the json with the modified attribute, backbone calls this url:
Remote Address:127.0.0.1:3000
Request URL:http://www.lvh.me:3000/api/user/1/tickets
Request Method:PUT
without the ticket id!
Is there any way to prevent backbone fire an update when server return the model with different attributes?
The problem was that I had a listener in my model exactly on the column that server changed:
initialize: function() {
this.on("change:status", this.statusChanged, this);
},
Now I had to figure out why the update url does not contain the model id.
I figured out that when I first created the model, from some reasons I couldn't assign it to the collection, so in order to save it I assign the url manually:
var newTicket = new MyApp.Ticket( ticketData );
newTicket.url = this.collection.url();
Now, the bug is that url is a function, and I simply overrided it!
I changed the code to:
newTicket.urlRoot = this.collection.url();
and now it works.
Backbone will always perform PUT if your model has an id attribute setted. Which makes sense when using RESTfull.
Be sure that you're really SAVING(new model withoud an ID) a data to server instead of UPDATING(model with an ID) to server.