持续重绘视图 编辑页面
英文原文:http://emberjs.com/guides/cookbook/working_with_objects/continuous_redrawing_of_views
问题
有时视图需要每隔几秒或者几分钟重绘一次。例如更新相对时间(如同twitter.com那样)。
解决方案
应用中有一个时钟对象,该对象有一pulse
属性定时递增。希望将视图与pulse
绑定,并在其增加时得到刷新。
时钟对象可以创建用于绑定到应用生成的新视图的对象,比如评论列表。
讨论
ClockService对象
这里ClockService
只是用于作为一个例子,它可能来自于一个第三方库。并且通过初始化注入到应用中。
在初始化过程中,tick
方法通过Ember.run.later
每250毫秒被调用一次。当到时间时,会设置一个属性。由于tick
方法观察了一个递增属性,并且每次属性增加时另外一个周期也同时被触发。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
var ClockService = Ember.Object.extend({ pulse: Ember.computed.oneWay('_seconds').readOnly(), tick: function () { var clock = this; Ember.run.later(function () { var seconds = clock.get('_seconds'); if (typeof seconds === 'number') { clock.set('_seconds', seconds + (1/4)); } }, 250); }.observes('_seconds').on('init'), _seconds: 0, }); |
绑定至pulse
属性
在本技巧中,应用在初始化时注入了一个ClockService
的实例,并且将一个控制器的clock
属性设置为该实例。
1 2 3 4 5 6 7 |
Ember.Application.initializer({ name: 'clockServiceInitializer', initialize: function(container, application) { container.register('clock:service', ClockService); application.inject('controller:interval', 'clock', 'clock:service'); } }); |
该控制器可以基于注入的clock
实例的pulse
属性来设置任意属性。
本例中seconds
属性绑定到控制器的
clock对象的
pulse属性。属性
clock.pulse`在初始化时被注入。
控制器有(会话)数据来显示seconds
给访问者,而且少数用于Handlebars模板的条件属性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
App.IntervalController = Ember.ObjectController.extend({ secondsBinding: 'clock.pulse', fullSecond: function () { return (this.get('seconds') % 1 === 0); }.property('seconds'), quarterSecond: function () { return (this.get('seconds') % 1 === 1/4); }.property('seconds'), halfSecond: function () { return (this.get('seconds') % 1 === 1/2); }.property('seconds'), threeQuarterSecond: function () { return (this.get('seconds') % 1 === 3/4); }.property('seconds') }); |
一个评论列表的控制器,每条评论在被添加到列表时,会得到一个新的时钟实例。评论条目控制器设置seconds
绑定,用于在模板中显示评论创建了多长时间。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
App.CommentItemController = Ember.ObjectController.extend({ seconds: Ember.computed.oneWay('clock.pulse').readOnly() }) App.CommentsController = Ember.ArrayController.extend({ needs: ['interval'], itemController: 'commentItem', actions: { add: function () { this.addObject(Em.Object.create({ comment: $('#comment').val(), clock: ClockService.create() })); } } }); |
显示pulse
的Handlebars模板
seconds
的值是从pulse
属性计算得来的。控制器有些属性是用来选择一个控件来渲染的,fullSecond
、quarterSecond
、halfSecond
和threeQuarterSecond
。
评论列表的一个模板:
格式化时钟显示(h:m:s)的Handlebars助手
本助手在模板中这样使用:{{digital_clock seconds}}
,seconds
是控制器要显示的一个属性(h:m:s)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Ember.Handlebars.registerBoundHelper('digital_clock', function(seconds) { var h = Math.floor(seconds / 3600); var m = Math.floor((seconds % 3600) / 60); var s = Math.floor(seconds % 60); var addZero = function (number) { return (number < 10) ? '0' + number : '' + number; }; var formatHMS = function(h, m, s) { if (h > 0) { return '%@:%@:%@'.fmt(h, addZero(m), addZero(s)); } return '%@:%@'.fmt(m, addZero(s)); }; return new Ember.Handlebars.SafeString(formatHMS(h, m, s)); }); |
注意
为了深入探究这个概率,可以尝试添加一个时间戳,并通过与当前时间比较来更新时钟的pulse
。在用户将计算机设置为睡眠后,再唤醒后重新打开浏览器时也应该更新pulse
属性。
链接
源代码:
更多相关内容: