出版物订阅观察

时间:2013-08-19 18:35:48

标签: meteor observer-pattern publish-subscribe meteorite

我正在开展一个项目,我希望在地图上显示标记。

这些标记应该从具有视口约束的服务器发布。这意味着只发布了当前用户视口内的标记。

该出版物看起来像这样:

//server
Meteor.publish('posts', function(bottom_left_x, bottom_left_y, upper_right_x, upper_right_y, limit) {

  return Posts.find({locs: {$geoWithin: {$box:
                                  [[bottom_left_x, bottom_left_y],
                                   [upper_right_x, upper_right_y]]}}},
                       {sort: {submitted: -1}, limit: limit});
});

当我的map_center发生变化时,我总是通过订阅调用此函数:

//client
google.maps.event.addListener(map, 'idle', function(event) {
  var bounds = map.getBounds();

  var ne = bounds.getNorthEast();
  var sw = bounds.getSouthWest();
  postsHandle= Meteor.subscribe('posts', sw.lat(), sw.lng(), ne.lat(), ne.lng(), 10);
});

直到现在一切正常。 此外,我在帖子上创建了一个观察功能,在调用“添加”时呈现标记,在调用“删除”时删除。观察是非常好的渲染新标记和破坏旧标记

//client
Posts.find().observeChanges({
  added: function(post) {
  // when 'added' callback fires, add HTML element
    var marker = new google.maps.Marker({
      position: new google.maps.LatLng(post.locs.lat, post.locs.lng),
      postId: post._id,
      map: map,
    });
},removed .... and so on

问题是在整个Posts-Collection上触发了observe-Callback。但我只是想显示用户视口内的标记。这就是为什么我通常要做这样的事情:

//client
Posts.find({locs: {$geoWithin: {$box:
                                  [[bottom_left_x, bottom_left_y],
                                   [upper_right_x, upper_right_y]]}}},
                       {sort: {submitted: -1}, limit: limit}).observeChanges({

但那不可能。在minimongo中不支持GeoWithin,并且无法使用具有限制的集合调用oberserve。

有谁知道如何实现这一目标? 也许有一种方法可以将我从subcription直接获得的帖子直接推送到地图而不使用minimongo上的查询?

1 个答案:

答案 0 :(得分:1)

解决方案非常简单!

Meteor.autosubscribe( function () {
  Meteor.subscribe( 'chat', { room: Session.get( 'currentRoom' ) } );
} );

如果您希望通过更改视口范围来限制对地图视口的订阅,则必须使用自动订阅。似乎autosubscribe负责更改订阅参数:)

Meteor.autosubscribe( function () {
  var a = Session.get('bounds');
  if(a)
    Meteor.subscribe( 'posts', a.swlat, a.swlng, a.nelat, a.nelng, 5 );
} );