仅将事件ajaxStart()和ajaxStop()附加到当前主干视图
我正在为我正在构建的应用程序使用主干网。在这个应用程序中,我有一个主视图,它可以呈现一个模板,其中包含两个其他视图。一个标题视图和另一个包含某些内容的视图。header视图仅用于与content视图交互,并具有特定的功能 在header模板和content模板中,我有相同的代码,一个隐藏的DIV,带有一个加载程序图像,在进行ajax调用时显示该图像。我遇到的问题是,当我第一次加载应用程序时(或者当我刷新内容视图时),内容视图正在从ajax请求加载一些数据,但加载程序同时显示在标题和内容模板中(就像ajaxStart()是未附加到视图的全局事件一样) 以下是内容视图设置: 如您所见,我正在使用一段难看的代码来附加ajaxStart/ajaxStop事件:仅将事件ajaxStart()和ajaxStop()附加到当前主干视图,ajax,backbone.js,backbone-views,Ajax,Backbone.js,Backbone Views,我正在为我正在构建的应用程序使用主干网。在这个应用程序中,我有一个主视图,它可以呈现一个模板,其中包含两个其他视图。一个标题视图和另一个包含某些内容的视图。header视图仅用于与content视图交互,并具有特定的功能 在header模板和content模板中,我有相同的代码,一个隐藏的DIV,带有一个加载程序图像,在进行ajax调用时显示该图像。我遇到的问题是,当我第一次加载应用程序时(或者当我刷新内容视图时),内容视图正在从ajax请求加载一些数据,但加载程序同时显示在标题和内容模板中(就
this.el
.ajaxStart(function(){self.showLoader(self.el);})
.ajaxStop(function(){self.hideLoader(self.el);});
我过去经常这样做:
this.el
.ajaxStart(self.showLoader())
.ajaxStop(self.hideLoader());
showLoader: function(){
//this.$('#ajax_loader').show();
console.log('Ajax request started...');
},
hideLoader: function(){
this.$('#ajax_loader').hide();
console.log('Ajax request ended...');
},
initialize: function(params)
{
var self = this;
console.log(this.el);
_.bindAll(this, 'showLoader', 'hideLoader');
this.$el
.ajaxStart(this.showLoader)
.ajaxStop(this.hideLoader);
this.render(function(){
self.list = new App.Collection.List();
self.refresh(1, 10);
});
},
...
render: function(callback)
{
console.log('Rendering post by page...');
this.$el.html(this.template.render({
}));
if (undefined != callback) {
callback();
}
}
var f = o.m;
f();
$('#ajax_loader', el).show();
this.$('#ajax_loader').show();
但是,无论出于什么原因,我仍然没有定义,this.el
没有在showLoader()
和hideLoader()
中定义
我认为ajaxStart()
和ajaxStop()
被附加到this.el
DOM,并且只有这个视图能够侦听它。但是我的headerView具有完全相同的设置(除了加载的细枝模板),它显然接收到事件并显示加载程序
为了确保这种行为,我在内容视图中注释掉了showLoader()
,加载程序仍然显示在标题视图中
我不知道我做错了什么:(
编辑(在“mu太短”的回答之后):
“我的内容”视图现在看起来如下所示:
this.el
.ajaxStart(self.showLoader())
.ajaxStop(self.hideLoader());
showLoader: function(){
//this.$('#ajax_loader').show();
console.log('Ajax request started...');
},
hideLoader: function(){
this.$('#ajax_loader').hide();
console.log('Ajax request ended...');
},
initialize: function(params)
{
var self = this;
console.log(this.el);
_.bindAll(this, 'showLoader', 'hideLoader');
this.$el
.ajaxStart(this.showLoader)
.ajaxStop(this.hideLoader);
this.render(function(){
self.list = new App.Collection.List();
self.refresh(1, 10);
});
},
...
render: function(callback)
{
console.log('Rendering post by page...');
this.$el.html(this.template.render({
}));
if (undefined != callback) {
callback();
}
}
var f = o.m;
f();
$('#ajax_loader', el).show();
this.$('#ajax_loader').show();
和我的标题视图:
...
showLoader: function(){
this.$('#ajax_loader').show();
//console.log('Ajax request started...');
},
hideLoader: function(el){
this.$('#ajax_loader').hide();
console.log('Ajax request ended...');
},
initialize: function(params)
{
var self = this;
_.bindAll(this, 'showLoader', 'hideLoader');
this.$el
.ajaxStart(this.showLoader)
.ajaxStop(this.hideLoader);
this.models.Link = new App.Model.Link();
this.render();
},
render: function(callback)
{
this.$el.html(this.template.render({
data: []
}));
if (undefined != callback) {
callback();
}
}
...
但是加载程序仍然显示在标题视图模板中
PS:this.showLoader()
不是一个打字错误,因为我想在当前主干视图中调用函数。JavaScript函数的上下文(也称为this
)取决于函数的调用方式,而不是函数定义的上下文。考虑到以下情况:
this.el
.ajaxStart(self.showLoader())
.ajaxStop(self.hideLoader());
showLoader: function(){
//this.$('#ajax_loader').show();
console.log('Ajax request started...');
},
hideLoader: function(){
this.$('#ajax_loader').hide();
console.log('Ajax request ended...');
},
initialize: function(params)
{
var self = this;
console.log(this.el);
_.bindAll(this, 'showLoader', 'hideLoader');
this.$el
.ajaxStart(this.showLoader)
.ajaxStop(this.hideLoader);
this.render(function(){
self.list = new App.Collection.List();
self.refresh(1, 10);
});
},
...
render: function(callback)
{
console.log('Rendering post by page...');
this.$el.html(this.template.render({
}));
if (undefined != callback) {
callback();
}
}
var f = o.m;
f();
$('#ajax_loader', el).show();
this.$('#ajax_loader').show();
当您通过普通函数f
调用o.m
时,o.m
中的此
通常是全局上下文(浏览器中的窗口
)。您还可以使用和选择不同的此
,因此:
f.call(o);
会使这个
成为你所期望的o
。我应该提到的是,在大多数JavaScript环境中,你可以强制选择这个
,但我不想太离题
关键是:
this.el
.ajaxStart(this.showLoader)
.ajaxStop(this.hideLoader);
不足以确保showLoader
和hideLoader
将在正确的上下文中运行;我还假设您在showLoader
和hideLoader
末尾的括号只是打字错误
在主干应用程序中强制上下文的最常见方法是在初始化中使用:
initialize: function(params) {
_.bindAll(this, 'showLoader', 'hideLoader');
//...
基本上,它将this.showLoader
和this.hideLoader
替换为与包装器大致相同的内容:
function() { self.showLoader(self.el) }
将.bindAll
放置到位后,将:
this.el
.ajaxStart(this.showLoader)
.ajaxStop(this.hideLoader);
会很好的
顺便说一句,你不需要这样做:
this.el = params.el;
在初始化中,主干:
构造函数/初始化新视图([options])
[…]有几个特殊选项,如果通过,将直接附加到视图:模型
,集合
,el
,id
,类名
,标记名
和属性
你不需要这样做:
this.el
.ajaxStart(self.showLoader())
.ajaxStop(self.hideLoader());
showLoader: function(){
//this.$('#ajax_loader').show();
console.log('Ajax request started...');
},
hideLoader: function(){
this.$('#ajax_loader').hide();
console.log('Ajax request ended...');
},
initialize: function(params)
{
var self = this;
console.log(this.el);
_.bindAll(this, 'showLoader', 'hideLoader');
this.$el
.ajaxStart(this.showLoader)
.ajaxStop(this.hideLoader);
this.render(function(){
self.list = new App.Collection.List();
self.refresh(1, 10);
});
},
...
render: function(callback)
{
console.log('Rendering post by page...');
this.$el.html(this.template.render({
}));
if (undefined != callback) {
callback();
}
}
var f = o.m;
f();
$('#ajax_loader', el).show();
this.$('#ajax_loader').show();
或者,主干在视图中为您提供了一个相同的操作,而不隐藏参数列表末尾的el
;这样做:
this.el
.ajaxStart(self.showLoader())
.ajaxStop(self.hideLoader());
showLoader: function(){
//this.$('#ajax_loader').show();
console.log('Ajax request started...');
},
hideLoader: function(){
this.$('#ajax_loader').hide();
console.log('Ajax request ended...');
},
initialize: function(params)
{
var self = this;
console.log(this.el);
_.bindAll(this, 'showLoader', 'hideLoader');
this.$el
.ajaxStart(this.showLoader)
.ajaxStop(this.hideLoader);
this.render(function(){
self.list = new App.Collection.List();
self.refresh(1, 10);
});
},
...
render: function(callback)
{
console.log('Rendering post by page...');
this.$el.html(this.template.render({
}));
if (undefined != callback) {
callback();
}
}
var f = o.m;
f();
$('#ajax_loader', el).show();
this.$('#ajax_loader').show();
在主干方面更为惯用
此外,this.el
不一定是jQuery对象,所以不要这样做:
this.el.html(this.template.render({ ... }));
在渲染中
,使用缓存的:
感谢您宝贵的回复,但是加载程序仍然显示在标题模板中:(从我在文档中可以看到()ajaxStart()
是一个全局事件。每次有ajax请求时都会触发它。您不能执行$(DOM).ajaxStart(function(){console.log('triggered'));
并期望DOM元素触发ajax请求。我说得对吗?我的问题有什么解决方案:(?@maxwell2022:right,$(x)。ajaxStart()
是个谎言,因为它真正的意思是$(任何东西)。ajaxStart()
。您必须通过$.AJAX
参数或通过返回的jqXHR
绑定到所需的特定AJAX调用。因为当我获取它时,正是集合神奇地触发了AJAX调用,所以我不能将其与$.AJAX绑定,可以吗?另外,如果每个视图有20个AJAX调用,我只想触发一个我绑定到视图中以显示同一加载程序的事件。集合具有您可能可以使用的成功和错误回调。如果要添加“开始提取”,您还可以提供自己的sync
和fetch
方法事件。我通常在执行fetch
之前放置加载程序,然后在fetch
完成获取后调用render
时,加载程序就会离开。