重叠的流星出版物

时间:2017-05-16 16:25:02

标签: meteor subscriptions meteor-publications

我有一个流星应用程序,有2个帖子的出版物。所有帖子一个,特色帖子一个。有2个特色帖子 - “Post 1”和“Post 4”。我在所有页面上显示精选帖子,而我分页按名称排序的所有帖子(包括精选帖子)。当我在页面之间旅行时,来自2个出版物的数据会混淆并显示不正确的结果。

以下是代码:

Meteor.publish('posts', function(page) {
  const skip = parseInt(page && page !== '' ? page : 0) * 3
  return Posts.find({}, {
    limit: 3,
    skip,
    sort: {
      name: 1
    }
  });
});

Meteor.publish('featured', function() {
  return Posts.find({
    featured: true
  }, {
    sort: {
      name: 1
    }
  });
});

在客户端上,我订阅了两个并在2个循环中显示数据

Template.hello.onCreated(function helloOnCreated() {
  const instance = this;
  instance.autorun(function() {
    instance.subscribe('posts', FlowRouter.getParam('page'))
    instance.subscribe('featured')
  });
});

Template.hello.helpers({
  posts() {
    return Posts.find({}, {
      limit: 3,
      sort: {
        name: 1
      }
    })
  },
  featured_posts() {
    return Posts.find({
      featured: true
    }, {
      sort: {
        name: 1
      }
    });
  }
});

HTML模板如下:

<template name="hello">
  <h2>Featured</h2>
  {{#each featured_posts}}
    {{> post}}
  {{/each}}
  <h2>Posts</h2>
  {{#each posts}}
    {{> post}}
  {{/each}}
</template>

问题是来自2个订阅的数据在显示中混淆了。

在第1页上,它正确显示:

Page 1

Featured
  post 1
  post 4

All Posts
  post 1
  post 2
  post 3

但是当我转到第2页时

Page 2

Featured
  post 1
  post 4

All Posts  -- Should be
  post 1        post 4
  post 4        post 5
  post 5        post 6

在“帖子”里面显示“帖子1”,但是不应该在第2页。当我转到第3页时,我看到“帖子1”和“帖子4”,但他们不应该在那里。

我理解出版物和订阅的工作方式以及发生这种情况的原因 - 因为出版物合并了数据集。我想知道是否有办法将它们分开?

2 个答案:

答案 0 :(得分:1)

如果我理解正确,您的网页会对应您的&#34;所有帖子&#34;名单。 &#34;页面&#34;号码作为您的订阅参数发送,以便您收到一个简短的帖子列表。

这里的困难确实是您的客户端集合没有掌握所有文档(因为您在'posts'出版物中限制了它们),因此您不能使用类似于skip中的'posts'逻辑出版物。

如流星指南中所提出的&gt; Paginating subscriptions,您可以使用percolate:find-from-publication Atmosphere包轻松检索来自// Server FindFromPublication.publish('posts', function(page) { // Same logic const skip = parseInt(page && page !== '' ? page : 0) * 3 return Posts.find({}, { limit: 3, skip, sort: { name: 1 } }); }); // Client (no change in subscription) Template.hello.helpers({ posts() { return Posts.findFromPublication('posts', {}, { sort: { name: 1 } }); } // (no change in featured_posts) }); 出版物的文档,并且只能检索它们。

public function handle($request, Closure $next)
{
    if (!Auth::check()) {
        if ($request->ajax()) {
            return response('Unauthorized.', 401);
        } else {
            return redirect()->guest('/');
        }
    }
    else
    {
        $user = Auth::user();            
        if (!$user->activated) {
            $activation = action('Auth\AuthController@getActivationMail', ['username' => $user->username]);
            Auth::logout();

            return redirect()->guest('auth')
                    ->withErrors(array('message' => 'Please activate your account. Re-send your activation by clicking <a href=' . $activation . '>here</a>.'));
        }           
        else if (!$user->enabled) {
            Auth::logout();

            return redirect('/auth')->withErrors(array('message' => 'Your account has been deactivated. Please email ... for any inquiries.'))->withInput();
            // I tried to add the same method as the above if statement but not working here
        }

        $user->runDailyNotifications();
    }
    return $next($request);
}      

答案 1 :(得分:1)

我建议使用observe or observeChanges,以便可以在客户端上隔离发布的数据。文档可能令人生畏,但它实际上比它看起来更容易。

只需创建一个特殊的客户端集合,然后在observe回调中使用该集合的名称即可。请注意,客户端集合名称"featured_posts"用于对出版物中self.addedself.changedself.removed的调用:

// client-side
const FeaturedPosts = new Mongo.Collection('featured_posts', {
  defineMutationMethods: false
});

// server-side
Meteor.publish('featured', function() {
    const self = this;

    const handle = collection.find(selector, opts).observe({
      added: function(doc) {
        self.added('featured_posts', doc._id, doc);
      },

      changed: function(newDoc, oldDoc) {
        self.changed('featured_posts', newDoc._id, newDoc);
      },

      removed: function(doc) {
        self.removed('featured_posts', doc._id);
      },
    });

    self.ready();

    self.onStop(function(err) {
      if (!err) {
        handle.stop();
      }
    });
  });
};