点击事件未触发

时间:2012-05-09 12:17:06

标签: javascript backbone.js backbone-events backbone-views

我现在已经看了一会儿,但却找不到任何可能导致这种情况的原因。

我的代码:

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>

所有必需的元素都存在(据我所知)并且我没有手动设置View的el属性。我很遗憾,为什么在点击<h3>时事件没有绑定/触发。

编辑如果我不使用路由器并自行创建视图,则不会抛出任何错误并且功能正常工作。 e.g。

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

1 个答案:

答案 0 :(得分:3)

您的问题出在路由器中。就在这里:

resetPage: function() {
    $('body').removeClass('page-faq');
    this.faqView.remove();
}
默认情况下,{p> View#removeel视图上只有jQuery's remove而且:

  

[...]方法从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/

您可以尝试在remove中的被覆盖的faqView方法中使用detach进行操作,但实际上并不需要一直有faqView个实例:在需要时创建它,然后在不需要时删除它。