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视图的属性。我不知道为什么单击 时事件没有绑定/触发<h3>

编辑如果我不使用路由器并自行创建视图,则不会引发错误并且该功能有效。例如

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

1 回答 1

3

你的问题出在你的路由器上。实际上就在这里:

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

View#remove默认情况下只是视图上的jQueryremoveel,并且:

[...] 方法从 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在一个被覆盖的remove方法中搞乱,faqView但实际上没有必要一直都有一个faqViewaround 的实例:当你需要它时创建它,不需要它时删除它。

于 2012-05-09T21:02:17.973 回答