web-dev-qa-db-ja.com

キャッシュされたbackbone.jsのフェッチ結果

次のbackbone.jsコントローラーのインデックスアクションでフェッチを使用しています。

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.");
            }
        });
    }
});

問題は、結果がキャッシュされていることです。データベースの変更は反映されません。とにかく、結果をキャッシュしないようにbackbone.jsに指示する方法はありますか?

コレクションのURLをオーバーライドしてタイムスタンプを追加できることはわかっていますが、それより少しクリーンなものを探しています。

41
dagda1

これはIE=の問題であり、バックボーンは通常それとは関係ありません。jQueryajax呼び出しに移動してドキュメントを確認する必要があります。バックボーンはjquery ajaxをsyncメソッドに使用します。次のようにして、すべてのブラウザーでajax呼び出しを強制できます。

$.ajaxSetup({ cache: false });

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

57
Julien

@Julienの推奨は機能しますが、すべてのAJAX=要求はサーバーにヒットし、キャッシュから何も取得されません。

$.ajaxSetup({ cache: false });

これを行う別の方法があります。フェッチのオプションとして「キャッシュ:false」を渡すことができます(以下のコードを参照)。 "cache:false"を持つフェッチは常にサーバーにヒットし、他のフェッチはキャッシュからデータを取得できるという利点があります。現在作成しているアプリケーションは、データとコンテンツに非同期でアクセスします。アイテムをキャッシュから取得したい場合もあれば、サーバーにアクセスしたい場合もあります。

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

jQuery.ajaxオプションをフェッチオプションとして直接渡すこともできるため、ページ分割されたコレクションの特定のページをフェッチするには、Documents.fetch({data:{page:3}})

このコードと同様に、コレクションのフェッチメソッドをオーバーライドすることもできます。

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

以下、フェッチに「cache:false」を追加しました

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.");
            }
        });
37

別の解決策は、HTTPヘッダーを使用してサーバー側でのキャッシュを防ぐことです

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
?>

または、node.jsのexpressとcoffeescriptを使用したこのようなもの

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

取得に 'cache:false'を追加すると機能します!

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

開発ツールが使用されていないときにIEにのみ現れたバグを修正できました。

0
James Oh