0

私はしばらくの間見回しましたが、これの原因が何であるかを示唆するものを見つけることができませんでした.

私のコード:

var faqView = Backbone.View.extend({
    tagName: 'div',
    id: 'faq-list',
    initialize: function() {
        var view = this;
        this.collection = new faqCollection();
        this.collection.fetch({
            success: function(collection, response) {
                collection.each(function(faq){
                    view.$el.append(_.template($('script#faq_item').html(),{faq: faq.attributes}));
                });
            },
            error: function(collection, response) {
                view.$el.html("<p>Unable to get the FAQ items.<br>Please try again later.</p>");
            }
        });
    },
    render: function() {
        this.$el.appendTo('div#container');

        return this;
    },
    events: {
        'click h3': 'toggleAnswer'
    },
    toggleAnswer: function(event) {
        console.log(this);
        console.log(event);
    }
});

var router = Backbone.Router.extend({
    routes: {
        "faq": "faq",
        "*other": "defaultRoute"
    },
    faqView: {},
    initialize: function() {
        this.faqView = new faqView();
    },
    defaultRoute: function() {
        this.resetPage();
    },
    faq: function() {
        this.resetPage();
        $('body').addClass('page-faq');
        this.faqView.render();
    },
    resetPage: function() {
        $('body').removeClass('page-faq');
        this.faqView.remove();
    }
});

上記のコードは、 の最後の項目として含まれてい<body>ます。HTMLは以下の通りです。

<body>
    <div id="container">
    </div>
    <script type="text/template" id="faq_item">
        <h3 class="contracted"><span>{{faq.question}}</span></h3>
        <p style="display: none;">{{faq.answer}}</p>
    </script>
    <script type="text/javascript" src="./js/models.js"></script>
    <script type="text/javascript" src="./js/views.js"></script>
    <script type="text/javascript" src="./js/collection.js"></script>
    <script type="text/javascript" src="./js/router.js"></script>
    <script type="text/javascript">
        //<![CDATA[
            $(function() {
                var app = new router;
                Backbone.history.start();
            });
        //]]>
    </script>
</body>

すべての必要な要素が存在し (私が知る限り) el、View の属性を手動で設定していません。<h3>クリックしたときにイベントがバインド/起動されない理由がわかりません。

ルーターを使用せずにビューを自分で作成しても、エラーはスローされず、機能は機能します例えば

var app = new faqView();
app.render();
4

1 に答える 1

3

問題はルーターにあります。実際にここに:

resetPage: function() {
    $('body').removeClass('page-faq');
    this.faqView.remove();
}

View#removeデフォルトではビューのjQueryremoveだけであり、それは次のとおりです。el

[...] メソッドは DOM から要素を取り出します。[...] 要素に関連付けられたすべてのバインドされたイベントと jQuery データが削除されます

したがって、ビューのイベントを駆動this.faqView.remove()するdelegateハンドラーはなくなります。

通常のアプローチは、ビューを作成して後でキャッシュするのではなく、必要に応じてビューを作成して破棄することです。ルーターは次のようになります。

var router = Backbone.Router.extend({
    routes: {
        "faq": "faq",
        "*other": "defaultRoute"
    },
    defaultRoute: function() {
        this.resetPage();
    },
    faq: function() {
        this.resetPage();
        $('body').addClass('page-faq');
        this.view = new faqView();
        this.view.render();
    },
    resetPage: function() {
        $('body').removeClass('page-faq');
        if(this.view)
            this.view.remove();
    }
});

デモ: http://jsfiddle.net/ambiguous/aDtDT/

オーバーライドされたメソッドdetachの内部をいじることもできますが、常にインスタンスを保持する必要はありません。必要なときに作成し、不要なときに削除します。removefaqViewfaqView

于 2012-05-09T21:02:17.973 に答える