更新全局变量的骨干模型?

时间:2013-03-19 01:48:50

标签: backbone.js geolocation backbone-events

我有一个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?
  }
});

这里的正确方法是什么?

1 个答案:

答案 0 :(得分:4)

有两种方法可以解决这个问题。

位置是Backbone.Model

如果您的位置是骨干模型而不是简单变量,那么您可以执行以下操作:

// 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)
    },

我更喜欢第一种方法!