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

发布于 2024-12-22 23:11:38 字数 2607 浏览 0 评论 0原文

我正在创建一个日历应用程序。主视图显示单个月份,每个月都有每天的视图。

当月的数据用一个集合来表示,集合中的每个模型代表每天的数据。

现在,我想减少获取日历的服务器请求数量,因此每次我要求服务器获取结果时,我都会将其保存在一个对象中。

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;

我不完全确定上述方法是否正确,但当我尝试时,效果很好。

每天和每月的模型很简单。

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

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

每一天都有其视图,该视图构建在“MonthView.render()”函数内。

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

现在,我的问题出在 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!');
  }
});

但对于缓存的模型集合,上述绑定不起作用。我假设这与刷新视图时视图及其模型事件的绑定/取消绑定有关。

我遇到了问题

Backbone.js:重新填充或重新创建视图?

并且还浏览了文章

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

但我不太确定该做什么以及如何去做。

编辑:我尝试关闭缓存,但每次只请求服务器,一切正常。那么是因为有一个旧视图挂在某个地方绑定到缓存的模型吗?

编辑:(对于托马斯)呈现我的“月视图”如下。 MonthView 充当“父”视图,并将所有 Day 视图附加到其“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;

第一次显示日历时,上面的代码工作正常,但下次我访问同一个日历时,“day.set({selected:true})”似乎不会触发“this.model.bind” ” 在 DayView 文件中设置。

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.

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.

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?

And also went through the article

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 = 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夏日浅笑〃 2024-12-29 23:11:39

上面的代码在第一次显示日历时工作正常,但下次我访问同一个日历时,“day.set({selected:true})”似乎不会触发“this.set({selected:true})”。 model.bind”在 DayView 文件中设置。

从首次显示日历到下次访问日历之间,TODAY 变量的值是否发生变化?

如果 TODAY 值没有更改,那么当您首次显示日历并触发更改事件时,下面的代码会将 selected 设置为 true,但是下次访问日历时,它将设置在同一模型上将 selected 设置为 true,但不会触发更改事件,因为 selected 值已设置为 true 并且未更改。

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

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.

Is the value of the TODAY variable changing between the time you first display the calendar and the next time you access it?

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.

  if( day.toJSON().day == TODAY ) {
    day.set({selected:true});
  }
甲如呢乙后呢 2024-12-29 23:11:38

说明

模型下次不会触发视图是正常的,因为 Backbone JS 不会更改模型。

事实上,当您执行 day.set({selected:true}); 时,模型现在的属性 selectedtrue
因此,当您再次执行此操作时,Backbone 不会修改模型,因为它已将属性selected设置为true

解决方案

调用View的高亮函数不需要修改模型,直接从View实例调用:

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

Explications

It's normal that the model don't trigger the View the next time because Backbone JS don't change the model.

Indeed when you do day.set({selected:true});, the model has now a property selected to true.
So when you do once again, Backbone doesn't modify the model because it has already the property selected to true.

Solution

You don't need to modify the model to call the View's highlight function, call it directly from the View instance :

  if( day.toJSON().day == TODAY ) {
    each_day.highlight();
  }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文