我有一个Venue对象集合,它们都有自己的lat / long属性,使用它和用户位置我可以计算用户和每个场地之间的距离。
我的问题是我不仅可以在创建Venue对象时执行此操作,因此需要在更新位置变量时触发此计算,方法是通过观察位置变量或触发函数,我没有两种方法都取得了很大成功。
window.App = {};
// Venue Object
App.Venue = Backbone.Model.extend({
urlRoot: '/rest/venue',
defaults: {
distance: ''
},
initialize: function(){
console.log(App.position);
this.set('distance', getDistance(App.position.coords.latitude, App.position.coords.longitude, this.get('latitude'), this.get('longitude')));
},
events: {
// Doesn't seem to work
App.position.on('change', function() { console.log('change event'); })
},
updateDistance: function() {
console.log('updateDistance');
}
});
// Venues Collection Object
App.Venues = Backbone.Collection.extend({
url: '/rest/venues',
model: App.Venue,
comparator: function(venue) {
return venue.get('name');
}
});
$(document).ready(function(){
// Setup Model
App.venues = new App.Venues();
App.venues.fetch();
navigator.geolocation.watchPosition(gotPosition);
function gotPosition(position) {
console.log(position);
App.position = position;
// Somehow trigger updateDistance function on all model objects?
}
});
这里的正确方法是什么?
答案 0 :(得分:4)
有两种方法可以解决这个问题。
如果您的位置是骨干模型而不是简单变量,那么您可以执行以下操作:
// Give the position to each venue
App.venues = new App.Venues({position: position}); //doesn't matter if the position variable is just empty right now.
在App.Venue模型初始化方法中:
App.Venue = Backbone.Model.extend({
...
initialize: function(options) {
this.position = options.position //save the reference
this.listenTo(this.position, "change", positionChanged) //now your venue model is watching this position object. any change and positionChanged method will be called
},
positionChanged: function (model) {
// position updated
}
因此,由于某些原因,您没有Backbone模型的位置,那么您可以通过扩展Backbone.Events模块来设置自己的事件聚合器:
App.vent = _.extend({}, Backbone.Events);
每当更新位置时,您都会触发一个事件:
function gotPosition(position) {
console.log(position);
App.position = position;
App.vent.trigger("position:updated") // you could name this event anything.
}
在您的Venue模型中,您可以收听事件:
App.Venue = Backbone.Model.extend({
...
initialize: function(options) {
App.vent.on("position:updated", this.positionChanged)
},
我更喜欢第一种方法!