如何在angular-meteor上正确订阅

问题描述:

我是新来的角流星,试图做一个类似于Reddit的应用程序来练习。但我不确定什么是正确的订阅和发布方法。这是我的代码。如何在angular-meteor上正确订阅

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)然后按预期工作。

考虑到我只订阅getPostByBoard这是关于只在给定的董事会获得职位,我应该只能得到其中几个。我查看了控制台,如Posts.find({}).count(),而且令人惊讶的是它有每个帖子。

所以我的问题是我应该添加查询甚至在我订阅正确的发布功能后发现?或者我在某个时候错了?

无论何时在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

+0

感谢您的评论,但我有2个后续问题: 1:让客户端指定服务器端查询选项作为参数是不是非常危险?通过这种方式,他可以访问所有帖子(即使是私人的,如果存在这样的东西) 2:如果说Posts集合增长,并且我在其他地方有另一个订阅与其他标准匹配的帖子,他们也会在这里列出(因为通配符.find()),对吗? 预先感谢您的任何启发;) –

+0

1.服务器端发布方法确定允许或不允许用户接收用户。在这个例子中,它返回所有的帖子,但你可以很容易地添加一个你选择的过滤器来限制用户能够检索的内容。 2.通过使用meteorSubscribe,您将在更改视图时删除订阅。所以只要另一个订阅不是在同一个视图中同时发生的,它们也不会互相阻塞。 –