在模型默认情况下声明视图时不会触发事件

Events are not triggered when view is declared at model's default

背景

我在一个议程网络应用程序中工作,用户可以在其中 select "day"、"week" 和 "month" 视图。对于第一步,我创建了一个 Scheduler,它将包含一个 DayView 对象,尽可能简单。所以,我从这个 html 标记开始(忽略头部部分只是为了澄清代码源):

<body id="mjb-calendar">
    <div data-role="page" id="mjb-day-view">
        <div role="main" class="ui-content">
            <a class="test" href="#">Test</a>
        </div>
    </div>
</body>

我已经创建了 day model 模型和 day view 如下:

var Day = Backbone.Model.extend({
    defaults: {
        title: "Day"
    }
});

var DayView = Backbone.View.extend({
    el: '#mjb-day-view',
    events: {
        "click .test": 'test'
    },

    initialize: function() {
        _.bindAll(this, 'render');
        this.model = new Day();
        this.model.on('change', this.render);
    },
    test: function(){
        alert('test');
    },

    render: function() {
        console.log('day view rendered');
        return this;
    }
});

好的,请注意单击元素 .test 时会触发一个事件。因此,进行 运行 测试:

$(document).ready(function(){
    var day = new DayView();
});

单击 .test link 后,将正确提示警报。

嗯,为了让调度器更灵活,我创建如下:

var Scheduler = Backbone.Model.extend({
    defaults: {
        "view": new DayView()
    }
});

var SchedulerView = Backbone.View.extend({
    el: '#mjb-calendar',
    events: {},

    initialize: function(options) {

        _.bindAll(this, 'render');
        this.model = new Scheduler();
        this.render();
    },

    render: function() {
        this.model.get('view').render();
    }
});

请注意,我已将 DayView 声明为调度程序模型 ("view": new DayView()) 的属性。

问题

当我将调度程序视图初始化为...

$(document).ready(function(){
    var scheduler = new SchedulerView();
});

...为什么click .test事件不再触发?

资产

就像我在评论中提到的那样。 该代码应该可以工作。

http://jsfiddle.net/7mMGp/64/

 var Day = Backbone.Model.extend({
     defaults: {
         title: "Day"
     }
 });

 var DayView = Backbone.View.extend({
     el: '#mjb-day-view',
     events: {
         "click .test": 'test'
     },

     initialize: function() {
         _.bindAll(this, 'render');
         this.model = new Day();
         this.model.on('change', this.render);
     },
     test: function(){
         alert('test');
     },

     render: function() {
         console.log('day view rendered');
         return this;
     }
 });

 var Scheduler = Backbone.Model.extend({
     defaults: {
         "view": new DayView()
     }
 });

 var SchedulerView = Backbone.View.extend({
     el: '#mjb-calendar',
     events: {},

     initialize: function(options) {

         _.bindAll(this, 'render');
         this.model = new Scheduler();
         this.render();
     },

     render: function() {
         this.model.get('view').render();
     }
 });

 var schedulerView = new SchedulerView();

根据你放的代码,你必须首先创建一个schedulerView的实例。

然后 schedulerViewinitializenew Scheduler() 这使得 DayView 实例初始化。

所以程序流程是

schedulerView(主视图)-> schedulerModel -> DayView -> DayModel

这不是一个好的设计,但可以。

仅供参考,您可以改为执行类似的操作。

var Days = Backbone.Collection.extend({
 model: Day
});
var days = new Days()
//add or modify the Collection

并且在 SchedulerView 中,

render : function(){
  days.each(function(dayModel){
    new DayView({model : dayModel}).render();
  })
  return this
}

mainView(SchedulerView) 使用 dayModel 生成 subViews(DayView) 实例并调用它们的 render

关系简单。