Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/452.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 主干视图事件不';重新渲染后无法工作_Javascript_Javascript Events_Backbone.js_Jquery_Underscore.js - Fatal编程技术网

Javascript 主干视图事件不';重新渲染后无法工作

Javascript 主干视图事件不';重新渲染后无法工作,javascript,javascript-events,backbone.js,jquery,underscore.js,Javascript,Javascript Events,Backbone.js,Jquery,Underscore.js,我很紧张,在视图重新渲染后,我似乎无法让鼠标事件在我的主干视图上工作,除非我做了最荒谬的事情: $("a").die().unbind().live("mousedown",this.switchtabs); 实际上,我有这个,但决定更新到最新的主干,并尝试使用新的delegateEvents()函数 以下是我的项目id的结构: Appview / AppRouter | ----->PageCollection | -----

我很紧张,在视图重新渲染后,我似乎无法让鼠标事件在我的主干视图上工作,除非我做了最荒谬的事情:

$("a").die().unbind().live("mousedown",this.switchtabs);
实际上,我有这个,但决定更新到最新的主干,并尝试使用新的
delegateEvents()
函数

以下是我的项目id的结构:

Appview / AppRouter
  |
  ----->PageCollection
             |
             ------->PageView/PageModel
             ------->PageView/PageModel      these page view/models are not rendered
             ------->PageView/PageModel
             |
             ------->PageView/PageModel
                        |
                        ----->render()      *when a pageview is rendered*
                                |
                                -----> Creates new 
                                     Tabcollection
                                       |
                                       --->TabModel/TabView   <-- this is where the issue is 
Appview/AppRouter
|
----->页面收集
|
------->页面视图/页面模型
------->页面视图/页面模型不呈现这些页面视图/模型
------->页面视图/页面模型
|
------->页面视图/页面模型
|
----->呈现页面视图时呈现()*
|
----->创造新的
Tabcollection
|

--->TabModel/TabView当视图被重新渲染时,您是重复使用同一视图并再次调用render(),还是删除视图并创建一个全新的视图

无论哪种情况,原因似乎是视图事件在重新渲染视图之前未解除绑定。德里克·贝利对此有很好的理解


重新渲染时,1)确保解除旧视图中所有事件的绑定,2)创建一个新视图并渲染它

这行代码可能是您的问题:

this.delegateEvents()

去掉它,它应该会工作

您需要自己调用
delegateEvents
的唯一时间是当您拥有与视图的
events
散列分开声明的事件时。当您创建视图实例时,主干视图将为您调用此方法。

当使用
$(el).empty()
时,它将删除所选元素中的所有子元素,并删除绑定到所选元素内部任何(子)元素的所有事件(和数据)(
el

若要将事件绑定到子元素,但仍要删除子元素,请使用:

$(el).children().detach();
而不是
$(.el).empty();


这将允许您的视图在事件仍然绑定并工作的情况下成功重新渲染。

到目前为止,您采取了哪些步骤来解决此问题?我将尝试以下几件事:查看是否可以在处理
事件的主干源中设置断点。这可能会给您一些启示。另外,尝试使用Chrome的DOM和事件侦听器断点。这可能会帮助您检查是否有任何代码正在执行,或者事件是否只是无法连接。我已根据jq$(document.find)记录(“tab nav selected”)要查看呈现的项是否实际在dom上..可以得到正确的结果。在我自己的代码中,已通过断点。我没有足够的信心使用调试器挖掘主干本身。范围似乎都很好…我不确定,但似乎事件正在被重写但是,我不能在每个子视图更新时创建新的父视图(父视图必须响应子视图).奇怪的是,我在文章中尝试了这种方法,但奇怪的是,它每3次就工作1次,其他时候我重新加载了页面…没什么大不了的。很荣幸你能回答我的问题,我在你的博客上读到了一堆有用的主干内容。我已经放弃并使用jQuery。live…是的,这是一个讨厌的东西…但这是唯一的事情我正在工作,离截止日期还有两天。。humm@Alex在您的代码中尝试:
this.$el.children().detach().append(nav).append(tabcontent);
它应该可以完美地工作。无需重新创建视图的实例。请查看这些答案作为进一步的参考:和
var TabPanelView = Backbone.View.extend({
    className:      "tabpanel",
    html:           'no content',
    model:          null,
    rendered:       false,
    events:{
        'click a.tab-nav': 'switchtabs'
    },
    initialize: function(args)
    {
        this.nav            = $("<ol/>");
        this.views          = args.items;
        this.className      = args.classname?args.classname:"tabpanel";
        this.id             = args.id;
        this.container      = $("<section>").attr("class",this.className).attr("id",this.id);
        _.bindAll(this);
        return this.el
    },
    /*
    This render happens multiple times, the first time it just puts an empty html structure in place
    waiting for each of the sub models/views to load in (one per tab)
    */
    render: function(args){
        if(!args)
        {
            //first render
            var nav             = $("<aside/>").addClass("tab-navigation").append("<ol/>").attr("role","navigation");
            var tabcontent      = $("<section/>").addClass("tab-panels");
            for(i = 0;i<this.views.length;i++)
            {
                $("ol",nav).append("<li><a rel='"+this.views[i].id+"' href='javascript:;' class='tab-nav'></a></li>");
                tabcontent.append(this.views[i].el);
            }
            this.$el.empty().append(nav).append(tabcontent);
        }
        else if(args && args.update == true){
            // partial render -- i.e. update happened inside of child objects
            var targetid = args.what.cid;
            for(i = 0;i<this.views.length;i++)
            {
                var curcontent  = this.$el.find("div#"+this.views[i].id);
                var curlink     = this.$el.find("a[rel='"+this.views[i].id+"']")
                if(this.views[i].cid == targetid)
                {
                    curcontent.html($(this.views[i].el).html());
                    curlink.text(this.views[i].model.rawdata.header);
                }
                if(i>0)
                {
                    // set the first panel 
                    curcontent.addClass("tab-content-hide");
                }
                if(i==0)
                {
                    curcontent.addClass("tab-content-show");
                    curlink.addClass("tab-nav-selected");
                }
                // this ridiculous piece of jQuery is the *ONLY* this i've found that works
                //$("a[rel='"+this.views[i].id+"']").die().unbind().live("mousedown",this.switchtabs);
            }
        }
        this.delegateEvents();
        return this;
    },
    switchtabs: function(args){

        var tabTarget = args.target?args.target:false
        if(tabTarget)
        {
            this.$el.find("aside.tab-navigation a").each(function(a,b)
            {
                $(this).removeClass("tab-nav-selected")
            })
            $(tabTarget).addClass("tab-nav-selected");
            this.$el.find("div.tab-content-show").removeClass("tab-content-show").addClass("tab-content-hide");
            this.$el.find("div#"+tabTarget.rel).removeClass("tab-content-hide").addClass("tab-content-show");
        }
    }
});