简体   繁体   English

Backbone.js-缓存其视图和模型的事件的收集和绑定

[英]Backbone.js - Cached collection and binding of events of its views and models

I am creating a Calendar app. 我正在创建一个日历应用程序。 The main view displays a single month, and in each month there are views for each day. 主视图显示一个月,并且每个月都有每天的视图。

Data in the month is represented by a collection, and each model in the collection represents each day's data. 当月的数据由一个集合表示,该集合中的每个模型代表每天的数据。

Now, I wanted to reduce the number of server requests to get the calendar, so each time I ask the server to get me results, I save it in an object. 现在,我想减少获取日历的服务器请求的数量,因此,每次我请求服务器获取结果时,都将其保存在一个对象中。

var Calendar = Backbone.Router.extend({
  calendar_view  : new MonthView(),
  calendar_cache : new Object(),

  initialize:function() {
    calendar_view.display_calendar();
  }  
});

var MonthView = Backbone.View.extend({

  display_calendar : function() {
    if(calendar.calendar_cache[month]) {
      this.collection = calendar.calendar_cache[month];
      this.render();
    } else {
      // ... get the new calendar data from the server and save to the cache
    }
  }

  render:function() {
    // display calendar by building its views and rendering it.
  }
});

var cal = new Calendar();
var month = 10;

I'm not entirely sure if above is the right approach, but when I tried it, it worked well. 我不确定上述方法是否正确,但是当我尝试过时,它效果很好。

The model for each day and the month is simple. 每天和每月的模型都很简单。

var Month = Backbone.Collection.extend({
  model:Day
});

var Day = Backbone.Model.extend({});

Each day also has its view, which is built inside the "MonthView.render()" function. 每天都有自己的视图,该视图内置在“ MonthView.render()”函数中。

var DayView = Backbone.View.extend({
  ...
});

Now, my problem is in my DayView, I bind to a model change to kick off a certain event, as below. 现在,我的问题出在DayView中,我绑定到模型更改以启动某个事件,如下所示。

var DayView = Backbone.View.extend({
  initialize:function() {
    this.model.bind('change', this.highlight, this);
  },

  highlight:function() {
    console.log('This event should be fired whenever this view's model is changed!');
  }
});

But for the cached collection of models, the above binding isn't working. 但是对于缓存的模型集合,上述绑定不起作用。 I am assuming it's something to do with binding/unbinding of views and its model events when I refresh the views. 我假设这与刷新视图时绑定/取消绑定视图及其模型事件有关。

I went through questions 我遇到了问题

Backbone.js : repopulate or recreate the view? Backbone.js:重新填充还是重新创建视图?

And also went through the article 并且也浏览了这篇文章

http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/ http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/

But I'm not exactly sure what to do and how to go about this. 但是我不确定该怎么做以及如何去做。

EDIT : I tried turning OFF the caching, but just requesting the server every time and everything works fine. 编辑:我试图关闭缓存,但每次都只请求服务器,一切正常。 So is it because there is an old view hanging around somewhere that is binding to the cached model? 是不是因为有旧视图挂在与缓存模型绑定的某个地方?

EDIT : (For Thomas) rendering my "month view" is as follows. 编辑:(对于托马斯)渲染我的“月视图”如下。 MonthView acts as a 'parent' view, and appends all the Day view into its "el". MonthView充当“父”视图,并将所有“日”视图附加到其“ el”中。

MonthView = Backbone.View.extend({
  ...
  ...
  render:function() {
    var self = this;
    this.collection.each(function(day) {
      var each_day = new DayView({ model: day });
      $(self.el).append(each_day.render().el);

      // highlight if each_day is "today", by modifying the model's attribute.
      if( day.toJSON().day == TODAY ) {
        day.set({selected:true});
      }
    }
  }
});

var TODAY = 23;

Above code works fine, when displaying the calendar for the first time, but next time I'm accessing the same calendar, "day.set({selected:true})" doesn't seem to fire the "this.model.bind" set in the DayView file. 上面的代码在第一次显示日历时效果很好,但是下次我访问同一日历时,“ day.set({selected:true})”似乎没有触发“ this.model.bind在DayView文件中设置。

Above code works fine, when displaying the calendar for the first time, but next time I'm accessing the same calendar, "day.set({selected:true})" doesn't seem to fire the "this.model.bind" set in the DayView file. 上面的代码在第一次显示日历时效果很好,但是下次我访问同一日历时,“ day.set({selected:true})”似乎没有触发“ this.model.bind在DayView文件中设置。

Is the value of the TODAY variable changing between the time you first display the calendar and the next time you access it? TODAY变量的值在第一次显示日历和下一次访问日历之间是否发生变化?

If the TODAY value doesn't change, then your following code below will set selected to true when you first display the calendar and fire the change event, however the next time you access the calendar, it will set selected to true on the same model, but the change event will not be fired because the selected value was already set to true and did not change. 如果今天值不发生变化,那么下面的下面的代码将设置选择为真当你第一次显示日历,并触发change事件,但您访问日历接下来的时间,它会集中选择到真正在同一个模型,但更改事件不会触发,因为所选值已设置为true且未更改。

  if( day.toJSON().day == TODAY ) {
    day.set({selected:true});
  }

Explications 说明

It's normal that the model don't trigger the View the next time because Backbone JS don't change the model. 由于Backbone JS不会更改模型,因此模型下次不会触发视图是正常的。

Indeed when you do day.set({selected:true}); 确实,当您执行day.set({selected:true}); , the model has now a property selected to true . ,模型现在具有选择true的属性。 So when you do once again, Backbone doesn't modify the model because it has already the property selected to true . 因此,当您再次执行此操作时,Backbone不会修改模型,因为它已经将属性选择true

Solution

You don't need to modify the model to call the View's highlight function, call it directly from the View instance : 您无需修改​​模型即可调用View的Highlight功能,而直接从View实例中调用它:

  if( day.toJSON().day == TODAY ) {
    each_day.highlight();
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM