发布于 2015-08-18 16:32:13 | 127 次阅读 | 评论: 0 | 来源: 网络整理
有时视图需要每隔几秒或者几分钟重绘一次。例如更新相对时间(如同twitter.com那样)。
应用中有一个时钟对象,该对象有一pulse属性定时递增。希望将视图与pulse绑定,并在其增加时得到刷新。
时钟对象可以创建用于绑定到应用生成的新视图的对象,比如评论列表。
这里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。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
{{#if fullSecond}}
{{nyan-start}}
{{/if}}
{{#if quarterSecond}}
{{nyan-middle}}
{{/if}}
{{#if halfSecond}}
{{nyan-end}}
{{/if}}
{{#if threeQuarterSecond}}
{{nyan-middle}}
{{/if}}
<h3>You've nyaned for {{digital_clock seconds}} (h:m:s)</h3>
{{render 'comments'}}
|
评论列表的一个模板:
1 2 3 4 5 6 7 |
<input type="text" id="comment" />
<button {{action add}}>Add Comment</button>
<ul>
{{#each}}
<li>{{comment}} ({{digital_clock clock.pulse}})</li>
{{/each}}
</ul>
|
本助手在模板中这样使用:{{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属性。
源代码:
更多相关内容: