web-dev-qa-db-fra.com

backbone.js récupère les résultats mis en cache

J'utilise fetch dans l'action d'index du contrôleur backbone.js suivant:

App.Controllers.PlanMembers = Backbone.Controller.extend({
    routes: {
        "": "index"
    },

    index: function () {
        var planMembers = new App.Collections.PlanMembers();

        planMembers.fetch({
            success: function () {
                var recoveryTeam = planMembers.select(function (planMember) {
                    return planMember.get("TeamMemberRole") == "RecoveryTeam";
                });

                var otherMembers = planMembers.select(function (planMember) {
                    return planMember.get("TeamMemberRole") == "Other";
                });

                new App.Views.Index({ collection: { name: "Team", members: recoveryTeam }, el: $('#recoveryTeam') });

                new App.Views.Index({ collection: { name: "Team", members: otherMembers }, el: $('#otherTeam') });
            },
            error: function () {
                alert('failure');
                showErrorMessage("Error loading planMembers.");
            }
        });
    }
});

Le problème est que les résultats sont mis en cache. Il ne prend pas les modifications de base de données. Est-il possible de dire à backbone.js de ne pas mettre en cache les résultats?

Je sais que je pourrais remplacer l'URL de la collection et ajouter un horodatage, mais je cherche quelque chose d'un peu plus propre que cela.

41
dagda1

C’est généralement un problème sur IE et le réseau principal n’a rien à voir avec cela. Vous devez descendre à l'appel ajax de jQuery et consulter le doc. Backbone utilise jquery ajax pour sa méthode de synchronisation. Vous pouvez faire quelque chose comme ceci pour forcer l'appel ajax sur tous les navigateurs:

$.ajaxSetup({ cache: false });

http://api.jquery.com/jQuery.ajaxSetup/

57
Julien

La recommandation de @ Julien fonctionnera, mais chaque demande AJAX atteindra le serveur et rien ne sera récupéré à partir du cache.

$.ajaxSetup({ cache: false });

Il y a une autre façon de faire cela. Vous pouvez passer "cache: false" en tant qu'option dans l'extraction (voir le code ci-dessous). L'avantage est que les fetchs qui ont "cache: false" atteindront toujours le serveur et que les autres fetch pourront extraire des données du cache. L’application que j’écris, accède aux données et au contenu de manière asynchrone. Parfois, je souhaite récupérer des éléments à partir de la mémoire cache et parfois, je souhaite accéder au serveur.

http://documentcloud.github.com/backbone/#Collection-fetch

les options jQuery.ajax peuvent également être passées directement en tant qu’options d’extraction, donc chercher une page spécifique d'une collection paginée: Documents.fetch ({data: {page: 3}})

Vous pouvez également redéfinir la méthode d'extraction de la collection de la même manière que le code this.

var PlanMembers = Backbone.Collection.extend({
     ...
     fetch: function (options) {
         options = options || {};
         options.cache = false;
         return Backbone.Collection.prototype.fetch.call(this, options);
     }
     ...
})

.

Ci-dessous, j'ai ajouté "cache: false" à la récupération

planMembers.fetch({
            cache: false,  //Hit the server
            success: function () {
                var recoveryTeam = planMembers.select(function (planMember) {
                    return planMember.get("TeamMemberRole") == "RecoveryTeam";
                });

                var otherMembers = planMembers.select(function (planMember) {
                    return planMember.get("TeamMemberRole") == "Other";
                });

                new App.Views.Index({ collection: { name: "Team", members: recoveryTeam }, el: $('#recoveryTeam') });

                new App.Views.Index({ collection: { name: "Team", members: otherMembers }, el: $('#otherTeam') });
            },
            error: function () {
                alert('failure');
                showErrorMessage("Error loading planMembers.");
            }
        });
36

Une autre solution consiste à empêcher la mise en cache côté serveur avec des en-têtes HTTP.

en php

<?php
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
?>

ou quelque chose comme ça dans node.js avec express et coffeescript

res.send results,
  "Cache-Control": "no-cache, must-revalidate"
  "Expires": "Sat, 26 Jul 1997 05:00:00 GMT"
3
Drew LeSueur

L'ajout de 'cache: false' pour chercher a fonctionné! 

this.foo.fetch({ cache:false });

J'ai pu corriger un bogue apparu dans IE uniquement lorsque les outils de développement n'étaient pas utilisés.

0
James Oh