バックボーンに、「コレクションのいずれかがデータをフェッチしているときはいつでも、スピナーを表示し、完了したら非表示にする」と簡単に言うことができるフックはありますか?
それよりも複雑になり、特定の機能を上書きする必要があると感じています。スピナーはいつ見せればいいですか? fetch()
またはrefresh()
または他の何かについて?
Collection::fetch()
の開始時にバックボーンはイベントをトリガーしないため( ソースコードを参照 )、fetch
メソッドをオーバーライドする必要があります。多分このようなもの:
var oldCollectionFetch = Backbone.Collection.prototype.fetch;
Backbone.Collection.prototype.fetch = function(options) {
this.trigger("fetch:started");
oldCollectionFetch.call(this, options);
}
これにより、fetch
メソッドがオーバーライドされ、フェッチの開始時にイベントが発生します。ただし、これは特定のコレクションインスタンスでのみイベントをトリガーするため、さまざまなコレクションが多数ある場合は、各コレクションでそのイベントをリッスンする必要があります。
JQueryajaxStartとajaxStopを使用できます。これらはajaxリクエストが行われるとグローバルに実行されるため、フェッチして保存すると実行されます。コードを追加して、最初にスピナーを表示し、最後に非表示にします。
backbone.js 1.0.0では、request
およびsync
イベントを使用できます http://backbonejs.org/#Events-catalog これはビューに表示されます。
initialize: function(){
this.items = new APP.Collections.itemCollection();
this.items.bind('request', this.ajaxStart, this);
this.items.bind('sync', this.ajaxComplete, this);
}
ajaxStart: function(arg1,arg2,arg3){
//start spinner
$('#item-loading').fadeIn({duration:100});
},
ajaxComplete: function(){
$('#item-loading').fadeOut({duration:100});
}
これは、コレクションごとまたはモデルごとに適用できます。スピナーのCSSを次に示します http://abandon.ie/notebook/simple-loading-spinner-for-backbonejs
バックボーンをオーバーライドせずにこれを行った方法は次のとおりです。
ビューで
var myView = Backbone.View.extend({
initialize; function(){
this.$el.addClass('loading');
collection.fetch(success:function(){
this.$el.removeClass('loading')
})
}
})
もう1つの方法は、モデルが追加されたときにローディングクラスを削除することです。通常、次のようになります。
var myView = Backbone.View.extend({
initialize; function(){
_.bindAll(this, 'addAll')
collection.bind('reset', this.addAll)
this.$el.addClass('loading');
collection.fetch();
},
addAll: function(){
this.$el.removeClass('loading');
collection.each(this.addOne);
}
})
これらはほとんどの場合ほぼ同じであり、ローダーは実際にはユーザーがコンテンツを表示する直前にそれを削除することを体験するためのものであるため、理にかなっています。
そして少し更新。 2012年12月13日以降、Backbone.syncに"request"
イベントが追加されました。このイベントは、サーバーへのリクエストが開始されるたびにトリガーされます。また、2012年1月30日以降、"sync"
イベントが追加されました。このイベントは、モデルの状態がサーバーと正常に同期されるたびにトリガーされます(作成、保存、破棄)。
したがって、ネイティブのバックボーンのメソッドをオーバーライドまたは拡張する必要はありません。 「フェッチの開始/終了」イベントをリッスンする場合、次のようにモデル/コレクションにリスナーを追加できます。
var view = new Backbone.View.extend({
initialize: function() {
this.listenTo(this.model, 'request', this.yourCallback); //start fetching
this.listenTo(this.model, 'sync', this.yourCallback); //finish fetching
}
});
どのモデルでもsync
というメソッドを作成でき、backbone.jsは同期するためにそれを呼び出します。または、メソッドBackbone.sync.
を単純に置き換えることができます。これにより、ソースコードの1か所でのみ変更を加えることができます。
私はバックボーンで NProgress を使用しましたが、これは最も機能的なローダー/スピナーです。
var view = Backbone.View.extend({
initialize: function () {
this.items = new APP.Collections.itemCollection();
this.items.on('reset', this.myAddFunction, this);
NProgress.start();
collection.fetch({
reset:true,
success: function () {
NProgress.done(true);
}
});
}
});
バックボーン同期メソッドを使用します。フェッチ、保存、更新、削除だけでなく、バックボーン同期メソッドを毎回呼び出します。
/ *同期アプリケーションのオーバーライドは、直接ajaxを除いてすべての要求が聞こえます* /
Backbone._sync = Backbone.sync;
Backbone.sync = function(method, model, options) {
// Clone the all options
var params = _.clone(options);
params.success = function(model) {
// Write code to hide the loading symbol
//$("#loading").hide();
if (options.success)
options.success(model);
};
params.failure = function(model) {
// Write code to hide the loading symbol
//$("#loading").hide();
if (options.failure)
options.failure(model);
};
params.error = function(xhr, errText) {
// Write code to hide the loading symbol
//$("#loading").hide();
if (options.error)
options.error(xhr, errText);
};
// Write code to show the loading symbol
//$("#loading").show();
Backbone._sync(method, model, params);
};