首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >只将事件ajaxStart()和ajaxStop()附加到当前主干视图

只将事件ajaxStart()和ajaxStop()附加到当前主干视图
EN

Stack Overflow用户
提问于 2012-08-27 08:33:45
回答 1查看 2.4K关注 0票数 4

我正在为我正在开发的应用程序使用主干。在这个应用程序中,我有一个主视图,它与其他两个视图在里面呈现一个模板。一个标题视图和另一个具有某些内容的视图。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事件:

代码语言:javascript
运行
复制
this.el
    .ajaxStart(function(){self.showLoader(self.el);})
    .ajaxStop(function(){self.hideLoader(self.el);});

我以前是这样的:

代码语言:javascript
运行
复制
this.el
    .ajaxStart(self.showLoader())
    .ajaxStop(self.hideLoader());

但是,无论出于什么原因,this.elshowLoader()hideLoader()中都没有定义。

我认为ajaxStart()ajaxStop()附在this.el DOM上,只有这个视图才能听到它。但是,我的headerView,它有完全相同的设置(除了加载的小枝模板),显然接收事件并显示加载程序。

为了确保这种行为,我在content视图中注释掉了showLoader(),加载程序仍然显示在header视图中。

我不知道我做错了什么

编辑(在回答"mu太短“后):

我的内容视图现在看起来如下所示:

代码语言:javascript
运行
复制
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();
            }
}

我的头视图是:

代码语言:javascript
运行
复制
...
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()不是一个错误,因为我想在当前主干视图中调用这个函数。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-08-27 08:59:48

this函数的上下文(AKA JavaScript )取决于函数的调用方式,而不是函数定义的上下文。考虑到这样的情况:

代码语言:javascript
运行
复制
var f = o.m;
f();

当通过普通函数f调用o.m时,o.m内部的this通常是全局上下文(浏览器中的window)。您还可以使用applycall来选择不同的this,因此如下所示:

代码语言:javascript
运行
复制
f.call(o);

将使this成为您所期望的o。我应该指出,在大多数this环境中,您可以使用bind强制选择JavaScript,但我不想太偏离方向。

重点是:

代码语言:javascript
运行
复制
this.el
    .ajaxStart(this.showLoader)
    .ajaxStop(this.hideLoader);

不足以确保showLoaderhideLoader在正确的上下文中运行;我还假设您在showLoaderhideLoader末尾的括号只是排字。

在骨干应用程序中强制使用上下文的最常见方法是在_.bindAll中使用initialize

代码语言:javascript
运行
复制
initialize: function(params) {
    _.bindAll(this, 'showLoader', 'hideLoader');
    //...

在本质上,它将this.showLoaderthis.hideLoader替换为或多或少相当于包装器的东西:

代码语言:javascript
运行
复制
function() { self.showLoader(self.el) }

一旦您准备好了这个_.bindAll,如下所示:

代码语言:javascript
运行
复制
this.el
    .ajaxStart(this.showLoader)
    .ajaxStop(this.hideLoader);

会很好的。

顺便说一句,你不需要这么做:

代码语言:javascript
运行
复制
this.el = params.el;

在您的initialize中,骨干那是为你做的

构造函数/初始化 new View([options]) ..。如果通过,有几个特殊选项将直接附加到视图:modelcollectionelidclassNametagNameattributes

你不需要这样做:

代码语言:javascript
运行
复制
$('#ajax_loader', el).show();

或者,主干在视图中为您提供了一个方法,它在不隐藏参数列表末尾的el的情况下执行相同的操作;这样做如下:

代码语言:javascript
运行
复制
this.$('#ajax_loader').show();

在脊梁上更有习性。

此外,this.el不一定是jQuery对象,所以不要这样做:

代码语言:javascript
运行
复制
this.el.html(this.template.render({ ... }));

在您的render中,使用缓存的this.$el代替:

代码语言:javascript
运行
复制
this.$el.html(this.template.render({ ... }));
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12138616

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档