我正在开发一个适用于世界各地的应用。我有一个余烬模型:Clock
我想每秒更新一次时钟的time
属性。
目前,我已经在时钟中定义了一个start
方法,负责更新时钟模型的时间属性。
我有两个问题:
1.如何从我的视图中调用模型的start
方法
2.我能采取更好的方法吗?
这是我的模型,视图,控制器,路由器和模板(如果你感兴趣的话):
型号:
App.Clock = DS.Model.extend({
city: DS.attr('string'),
country: DS.attr('string'),
latitude: DS.attr('string'),
longitude: DS.attr('string'),
time: DS.attr('date'),
order: DS.attr('number'),
start: function() {
var clock = this;
var updateTime = function() {
var timezoneService = Utilities.TimezoneService;
timezoneService.getTimezone(clock.get('latitude'), clock.get('longitude'), function(timezone) {
clock.set('time', timezoneService.getDateTime(timezone.offset));
});
};
updateTime();
window.setInterval(function() {
updateTime();
}, 1000);
}
});
查看:
App.ClocksView = Ember.View.extend({
templateName : 'world_clock/clocks'
});
App.ClocksNewView = Ember.View.extend({
templateName : 'world_clock/new'
});
控制器:
App.ClocksController = Ember.ArrayController.extend({
sortProperties: ['order']
});
App.ClocksNewController = Ember.ObjectController.extend({
city: null,
save: function() {
var cityName = this.get('city');
if(!cityName.trim()){
return;
}
var locationService = Utilities.LocationService.getInstance();
locationService.lookupLocation(cityName, function(location) {
var city = location.city;
var country = location.country;
var lat = location.latitude;
var lon = location.longitude;
if(city && country && lat && lon) {
var clks = App.Clock.find({ city: city });
clks.on('didLoad', function() {
if(clks.get('length') === 0) {
var clock = App.Clock.createRecord({
city: location.city,
country: location.country,
latitude: location.latitude,
longitude: location.longitude,
order: 10
});
clock.save();
}
});
}
});
this.set('city', '');
this.get('target').transitionTo('clocks');
}
});
路由器:
App.Router.map(function() {
this.resource('clocks', { path: '/' }, function() {
this.route('new');
});
});
App.ClocksRoute = Ember.Route.extend({
model: function() {
var locationService = Utilities.LocationService.getInstance();
locationService.getLocation(function(location) {
App.Clock.createRecord({
city: location.city,
country: location.country,
latitude: location.latitude,
longitude: location.longitude,
order: -10
});
});
return App.Clock.find();
}
});
clocks.handlebars:
{{outlet}}
{{#linkTo "clocks.new"}}Add Clock{{/linkTo}}
<ul>
{{#each controller}}
<li>{{city}}, {{country}} - {{time}}</li>
{{else}}
You have not defined any clock yet.
{{/each}}
</ul>
new.handlebars:
<form {{action "save" on="submit"}}>
{{view Ember.TextField valueBinding="city" placeholder="City"}}
<button>Save</button>
</form>
答案 0 :(得分:3)
如何从我的视图中调用模型的start方法
除极少数情况外,从视图中调用模型方法不是一个好主意。这说有可能。例如,您可以使用类似didInsertElement:
的内容{{each controller itemViewClass="App.ClockView" emptyViewClass="App.NoClocksView"}}
App.ClockView = Ember.View.extend({
template: Ember.Handlebars.compile("<li>{{city}}, {{country}} - {{time}}</li>"),
didInsertElement: function() {
var clock = this.get('content');
clock.start();
}
});
App.NoClocksView = Ember.View.extend({
template: Ember.Handlebars.compile("You have not defined any clock yet.")
});
这种方法的问题在于它有点破坏封装,这意味着许多微妙的事情可能会出错。例如,如果ember重新使用视图,那么它有一个新的时钟,但不运行didInsertElement。这就是Initializing State in didInsertElement不是一个好主意的原因。或者如果用户导航到此路线或从该路线导航,那么模型时钟将在后台运行,然后当用户返回时他们全部重新开始。这导致我:
我能采取更好的方法吗?
可能time
不应该是App.Clock
的属性。这不像你想在数据库中节省时间,对吗?一种选择是:
- 给App.Clock
计算属性以获得时区偏移量
- 将一个currentTime属性添加到clocksController
- 插入ClocksView后,使用setTimeout每秒刷新currentTime
- 制作一个呈现特定时钟的组件(世界时钟)
- 将计算属性time
添加到world-clock,它计算给定currentTime和时钟的时区偏移量的时间。
这样的事情:
<script type="text/x-handlebars" id="clocks">
{{outlet}}
{{#linkTo "clocks.new"}}Add Clock{{/linkTo}}
<ul>
{{#each clock in controller}}
<li>
{{world-clock city="clock.city" country="clock.country" offset="clock.offset" currentTime="currentTime"}}
</li>
{{/each}}
</ul>
</script>
<script type="text/x-handlebars" id="components/world-clock">
{{city}}, {{country}} - {{time}}
</script>
App.Clock = DS.Model.extend({
city: DS.attr('string'),
country: DS.attr('string'),
latitude: DS.attr('string'),
longitude: DS.attr('string'),
order: DS.attr('number'),
offset: function() {
var offset;
var service = Utilities.TimezoneService;
service.getTimezone(this.get('latitude'), this.get('longitude'), function(zone) {
offset = timezone.offset
});
return offset;
}.property('latitude', 'longitude')
});
App.WorldClockComponent = Ember.Component.extend({
tagName: 'li',
time: function() {
var service = Utilities.TimezoneService;
return service.getDateTime(this.get('offset'));
}.property('offset', 'currentTime');
});