1

我是 angular-meteor 的新手,并试图制作一个类似于 Reddit 的应用程序来进行练习。但我不确定订阅和发布的正确方法是什么。这是我的代码。

angular.module('app')
.config(($stateProvider) ->
  $stateProvider
  .state('boards-list',
    url: '/board'
    templateUrl: 'client/boards/boards-list.view.ng.html'
    controller: 'BoardsListCtrl'
  )
  .state('board-detail',
    url: '/board/:symbol'
    templateUrl: 'client/boards/board-detail.view.ng.html'
    controller: 'BoardDetailCtrl'
  )
)

我想在上面显示热门帖子/board,如果您转到特定版块,我想列出版块中的所有帖子。

这是板列表控制器

angular.module('app')
.controller('BoardsListCtrl', ($scope, $meteor, $modal, $log) ->
  $meteor.subscribe('getPopularPosts')
  $meteor.subscribe('getAllBoards')
  $scope.boards = $scope.$meteorCollection(->
    Boards.find({})
  )
  $scope.posts = $scope.$meteorCollection(->
    Posts.find({}, _.defaults(DEFAULT_QUERY_OPTIONS, limit: 5))
  )

  $scope.getHref = (link) -> if link then "http://#{link}" else "#"

  $scope.remove = (board) ->
    $scope.boards.remove(board)

  $scope.open = ->
    modalInstance = $modal.open(
      templateUrl: 'client/common/modal-new-board.view.ng.html'
      controller: 'ModalNewBoardCtrl'
    )
)

这是电路板细节控制器

angular.module('app')
.controller('BoardDetailCtrl', ($scope, $stateParams, $meteor, $modal) ->
  boardSymbol = $stateParams.symbol
  $scope.posts = []

  $scope.$meteorSubscribe('getBoardBySymbol', boardSymbol)
  $scope.board = $meteor.object(Boards, symbol: boardSymbol, false)
  $scope.$meteorSubscribe('getPostsByBoard', boardSymbol)
  $scope.posts = $scope.$meteorCollection(->
    Posts.find(board: boardSymbol, DEFAULT_QUERY_OPTIONS)
  )

  $scope.open = ->
    modalInstance = $modal.open(
      templateUrl: 'client/common/modal-post.view.ng.html'
      controller: 'ModalPostCtrl'
      resolve:
        symbol: -> $scope.board.symbol
    )
)

我的问题是,如果我Posts.find({}, DEFAULT_QUERY_OPTIONS)为 boardDetailCtrl 的 $scope.posts 编写,它实际上会显示所有帖子,就好像路由是/board状态改变时一样。当您直接访问该路线时,http://localhost:3000/angular它会获得适当的帖子。不知道为什么会这样,但我将其更改为Posts.find({board: boardSymbol}, DEFAULT_QUERY_OPTIONS)Then 它按预期工作。

考虑到我只订阅getPostByBoard是关于只在给定的板上发帖的,我应该只能得到其中的几个。我检查了控制台,Posts.find({}).count()并且令人惊讶的是它有每一个帖子。

所以我的问题是,即使在我订阅了正确的发布功能后,我是否应该添加查询来查找?还是我在某些时候错了?

4

1 回答 1

2

每当您在 Meteor 中开始订阅时,您都会将这些订阅的集合添加到本地集合中。因此,如果您有一个板块集合,并且在您的主页上订阅以查看所有集合,例如:

$meteor.subscribe('getAllBoards')

您正在将所有板添加到本地集合中。在您明确停止订阅之前,此本地集合将一直存在。因此,在您的董事会详细信息页面中,您仍然可以访问该完整集合。

如果您注意到您正在使用 2 种不同的订阅方法。$scope.$meteorSubscribe$meteor.subscribe。第一个将在 $scope 被销毁时自动删除订阅。第二个会保留它。

因此,如果您想在进入董事会详细信息页面时删除收藏并重新订阅,您也希望$scope.$meteorSubscribe在您的主页中使用。

这里有一些值得深思的地方。如果您在主页上并且使用$meteor.subscribe,那么您已经在本地获得了这些帖子的信息,对吗?因此,当您单击链接以查看董事会详细信息时,您实际上不需要再次订阅。你可以打电话:

  $scope.board = $meteor.object(Boards, symbol: boardSymbol, false);

您将可以访问该板信息。(我刚刚意识到您在谈论帖子而不是董事会,但想法仍然相同)。

简短回答:$meteor.subscribe()不会自行取消订阅,您必须告诉它。$scope.$meteorSubscribe确实取消订阅。

最佳实践?我会设置订阅选项,然后使用 find() 创建一个本地集合,例如:

$scope.$meteorSubscribe('getPopularPosts',  _.defaults(DEFAULT_QUERY_OPTIONS, limit: 5).then(-> {
      $scope.posts = $scope.$meteorCollection(->
          Posts.find();
      )
})

然后在您的发布中添加选项:

Meteor.publish('getPopularPosts', function(options) {
    return Posts.find({}, options);
});

这将限制发送给客户端的帖子数量,而不是发送所有帖子并且仅使用 5 个。

当您切换到董事会详细信息视图时,它将不再有此信息可让您绊倒,因为我们使用了$scope.$meteorSubscribe$scope.$meteorCollection

于 2015-08-12T15:54:01.630 回答