7

私は髪を引っ張っています。最もばかげたことをしない限り、ビューが再レンダリングされた後、マウスイベントをバックボーンビューで機能させることができないようです。

$("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 

タブコレクションには、すべてのタブを管理するためのメインタブビューがあり、タブごとに新しいモデル/ビューを作成し、タブが読み込まれるたびにリスナーにタブビューを再レンダリングさせます。タブビューが再レンダリングされると、その不自然なjQueryステートメントをそこに配置しない限り、マウスイベントは機能しなくなります。

ここにタブビューとレンダリングがあります(iveはそれをかなり取り除きました)

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");
        }
    }
});

バックボーンマウスイベントがまったく発生しない理由を誰かが考えることができますか?それは、それらがDOMにないためですか?これがバックボーンが特に役立つところだと思いましたか?...

4

3 に答える 3

6

このコード行はおそらくあなたの問題です:

this.delegateEvents();

それを削除すると、動作するはずです。

自分自身を呼び出す必要があるのは、ビューのハッシュdelegateEventsとは別に宣言されたイベントがある場合のみです。eventsビューのインスタンスを作成すると、Backboneのビューがこのメソッドを呼び出します。

于 2012-03-14T14:34:21.987 に答える
2

ビューが再レンダリングされているときに、同じビューを再利用して再度render()を呼び出すのですか、それともビューを削除してまったく新しいビューを作成するのですか?

いずれにせよ、原因は、ビューが再レンダリングされる前にビューイベントがバインド解除されていないことであるように見えます。デリックベイリーはこれについて素晴らしい投稿をしています。

再レンダリングするときは、1)古いビューのすべてのイベントのバインドを解除し、2)新しいビューを作成してレンダリングします。

于 2012-03-14T13:31:20.687 に答える
1

これを使用$(el).empty()すると、選択した要素内のすべての子要素が削除され、選択した要素内の任意の(子)要素にバインドされているすべてのイベント(およびデータ)が削除されます()。el

イベントを子要素にバインドしたまま、子要素を削除するには、次を使用します。

$(el).children().detach();それ以外の$(.el).empty();

これにより、イベントがバインドされて機能している状態で、ビューを正常に再レンダリングできます。

于 2014-03-12T12:40:28.393 に答える