我正在为我正在开发的应用程序使用主干。在这个应用程序中,我有一个主视图,它与其他两个视图在里面呈现一个模板。一个标题视图和另一个具有某些内容的视图。header视图仅用于与content视图交互,并具有特定的功能。
在标头模板和内容模板中,我有相同的代码,这是一个隐藏的DIV,带有加载程序映像,在执行ajax调用时显示。我遇到的问题是,当我第一次加载应用程序(或者当我刷新内容视图时),内容视图正在从ajax请求中加载一些数据,但是加载程序同时出现在标题和内容模板中(比如,如果ajaxStart()是一个全局事件,没有附加到视图中)。
以下是内容视图设置:
App.View.Content = Backbone.View.extend({ type:'test',模板: twig({ href:'/js/app/Template/Content.html.twig',异步: false }),块:{ test:twig({ href:'/js/app/Template/block/test.html.twig‘),异步: false },list:[],showLoader: console.log(El){console.log(‘console.log:',$(’#ajax_console.log‘,el));$('#ajax_loader',el).show();console.log('Ajax请求开始.‘);},hideLoader: hideLoader(El){$(’#Ajax_hideLoader‘,el).hide();console.log('Ajax请求结束.’);},初始化:函数(Params){ this.el = params.el;this.type = params.type连体this.type;var self = this;this.el this.typeThis.render(函数(){ self.list =新App.Collection.ListCollection();self.refresh(1,10);});},刷新:函数(页面,限制){ var self = this;console.log(‘刷新.’);$('#id-list-content').fadeOut('fast',function(){ $(This).html(‘);};this.list.type = this.type;this.list.page =Page溶胶- 1;this.list.limit =限值x= 10;this.list.fetch({ success: function(data){ //sole.log(data.toJSON());$.each(data.toJSON(),function()){//sole.log(this.type);var tpl_block = self.blockthis.type;如果(tpl_block !=未定义){ var块= tpl_block.render({ test: this };$( block ).appendTo(‘#id-list-.appendTo’);});$(#id-list-content‘).fadeIn(’fast‘;});};},呈现:函数(回调){console.log(’呈现列表.‘);this.el.html(this.template.render({ }));if (未定义的!=回调){回调();} });
如您所见,我正在使用一段丑陋的代码来附加ajaxStart / ajaxStop事件:
this.el
.ajaxStart(function(){self.showLoader(self.el);})
.ajaxStop(function(){self.hideLoader(self.el);});
我以前是这样的:
this.el
.ajaxStart(self.showLoader())
.ajaxStop(self.hideLoader());
但是,无论出于什么原因,this.el
在showLoader()
和hideLoader()
中都没有定义。
我认为ajaxStart()
和ajaxStop()
附在this.el
DOM上,只有这个视图才能听到它。但是,我的headerView,它有完全相同的设置(除了加载的小枝模板),显然接收事件并显示加载程序。
为了确保这种行为,我在content视图中注释掉了showLoader()
,加载程序仍然显示在header视图中。
我不知道我做错了什么
编辑(在回答"mu太短“后):
我的内容视图现在看起来如下所示:
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();
}
}
我的头视图是:
...
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()
不是一个错误,因为我想在当前主干视图中调用这个函数。
发布于 2012-08-27 08:59:48
this
函数的上下文(AKA JavaScript )取决于函数的调用方式,而不是函数定义的上下文。考虑到这样的情况:
var f = o.m;
f();
当通过普通函数f
调用o.m
时,o.m
内部的this
通常是全局上下文(浏览器中的window
)。您还可以使用apply
和call
来选择不同的this
,因此如下所示:
f.call(o);
将使this
成为您所期望的o
。我应该指出,在大多数this
环境中,您可以使用bind
强制选择JavaScript,但我不想太偏离方向。
重点是:
this.el
.ajaxStart(this.showLoader)
.ajaxStop(this.hideLoader);
不足以确保showLoader
和hideLoader
在正确的上下文中运行;我还假设您在showLoader
和hideLoader
末尾的括号只是排字。
在骨干应用程序中强制使用上下文的最常见方法是在_.bindAll
中使用initialize
。
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;
在您的initialize
中,骨干那是为你做的
构造函数/初始化
new View([options])
..。如果通过,有几个特殊选项将直接附加到视图:model
、collection
、el
、id
、className
、tagName
和attributes
。
你不需要这样做:
$('#ajax_loader', el).show();
或者,主干在视图中为您提供了一个方法,它在不隐藏参数列表末尾的el
的情况下执行相同的操作;这样做如下:
this.$('#ajax_loader').show();
在脊梁上更有习性。
此外,this.el
不一定是jQuery对象,所以不要这样做:
this.el.html(this.template.render({ ... }));
在您的render
中,使用缓存的this.$el
代替:
this.$el.html(this.template.render({ ... }));
https://stackoverflow.com/questions/12138616
复制相似问题