【问题标题】:Multiple filters on a collection with angular-meteor带有角流星的集合上的多个过滤器
【发布时间】:2015-11-04 18:11:09
【问题描述】:

我正在关注Meteor To-Do App tutorial with Angular integration 并正在学习过滤集合。通过遵循本教程中的原则,我已经能够在我正在开发的应用程序的集合上实现一个简单的过滤器,但现在我一直在试图弄清楚如何向过滤器添加多个查询。

在示例中,您可以通过切换复选框来查看未完成的任务。这是在控制器中实现的,通过观察 $scope.hideCompleted 的变化并将其作为 Mongo 查询传递以过滤 Meteor 集合。

观察者

$scope.$watch('hideCompleted', function() {
  if ($scope.hideCompleted)
    $scope.query = {checked: {$ne: true}};
  else
    $scope.query = {};
});

收藏过滤器

$scope.tasks = $meteor.collection(function() {
  return Tasks.find($scope.getReactively('query'), {sort: {createdAt: -1}})
});

如何使查询支持多个过滤器? 例如,假设我选择扩展示例并按优先级排列每个待办事项。然后我会有一个输入字段供用户按优先级过滤集合,其值绑定到$scope.priority。现在,如果我想通过不完整和 priority=$scope.priority 任务过滤待办事项列表,我知道 Mongo 查询需要类似于 Tasks.find({ $and: [{ checked: {$ne: true} },{ priority: $scope.priority }]},{ sort: { createdAt: -1 } })

在我的应用程序中,我已经能够让两个观察者正确跟踪对两个范围变量的更改,类似于我的示例 $scope.hideCompleted$scope.priority,但我不知道如何采取下一步过滤集合时合并查询。我还对this package 进行了一些修改,因为我最终希望能够按许多标准进行过滤和排序,但在切换到我在这里描述的概念之前我并没有走得太远.

如果能提供任何帮助,我将不胜感激。谢谢!

【问题讨论】:

    标签: angularjs meteor angular-meteor


    【解决方案1】:

    这将是我的方法:

    $meteor.autorun($scope, function() {
        // uncomment subscribe after you've got to that point
        // $scope.$meteorSubscribe('yourSubscription').then(function() {
            $scope.tasks = $scope.$meteorCollection(function() {
                return Tasks.find({ 
                    checked: $scope.getReactively('model.hideCompleted'),
                    priority: $scope.getReactively('model.priority')
                }, { sort: { createdAt: -1 } });
            });
        // });
    });
    

    这里有几件事:

    1. 删除autopublish 后,您可以取消注释$scope.$meteorSubscribe 方法并将"yourSubscription" 替换为您实际订阅的名称。
    2. 每次getReactively 变量更改时,$meteor.autorun 都会触发。
    3. $scope.$meteorSubscribe$scope.$meteorCollection 受到青睐,因为它们会在作用域被销毁时删除订阅和对象/集合。

    如果您有任何问题,也许我可以设置一个演示供您查看。

    【讨论】:

    • 这看起来很简单,用更少的行完成同样的事情。我在控制器的其他地方处理订阅,所以我可能需要做一些调整,但我认为我会更喜欢这种方法,因为它可以用更少的行完成同样的事情。我还需要阅读 $meteorSubscribe 和 $meteorCollection。
    • 太棒了,如果您在调整时遇到困难,请不要犹豫,开始一个新问题。另外,如果您不介意,请标记正确的答案,以便其他人更容易找到;)
    • 是的,我打算在测试后标记它。 :) 我今天早上正在尝试,它似乎工作得很好,调整我现有的代码也不错。但是,我注意到这将在模型发生任何更改之前应用过滤器(即,由于所有任务都分配了优先级,因此在开始时不返回待办任务,并且一旦客户端在输入表格)。
    【解决方案2】:

    好吧,我想我比我预期的要接近很多,所以我将回答我的问题并分享我为实现多个过滤器所做的工作,以实现关于待办事项应用程序的假设扩展。

    我将hideCompletedpriority 范围变量设置为范围对象model 的属性,并在最后使用带有参数true 的单个观察程序来检查对象是否相等(对于any 更改为 model 或其属性)。然后我通过拼接“子查询”生成$scope.query。我已经添加了下面的代码。

    目前这似乎工作正常,但我不确定它是否是最好的解决方案,所以我会继续试验,如果我发现更好的答案,我会更新我的答案。不过,我会对任何其他方法感兴趣!

    观察者

    var initQuery=true;    
    var subQueries=[];
    $scope.$watch('model', function() {
      if (!initQuery){
        subQueries=[];
        if ($scope.model.hideCompleted)
          subQueries.push({checked: {$ne: true}});
        if ($scope.model.priority)
          subQueries.push({priority: $scope.model.priority});
        $scope.query = { $and: subQueries};
      } else {
        initQuery = false;
        $scope.query = {};
      }
    }, true);
    

    筛选集合(未更改)

    $scope.tasks = $meteor.collection(function() {
      return Tasks.find($scope.getReactively('query'), {sort: {createdAt: -1}})
    });
    

    【讨论】:

    • 您是否正在构建所有查询客户端?如果我编辑您的 Tasks.find 调用会发生什么?确保您正在处理服务器端的规则
    • @Neil 您能否通过编辑我的 Tasks.find 调用并处理服务器端规则来扩展您的意思?我现在在这里使用两个答案的变体,但无论如何,在发布功能服务器端,我有查询、排序等规则。
    • 我只是指出你需要确保你在服务器端处理规则,这样如果我恶意编辑你的客户端 Task.find,我就不能弄乱你的数据库。大多数人使用允许/拒绝规则,但我发现这个库非常有用 - github.com/ongoworks/meteor-security
    • @Neil 好点。我注意到我遵循的教程通常假设用户不会尝试弄乱数据库,这有点令人失望。您是否有任何资源可以指点我,以便我可以学习以这种方式更好地保护应用程序?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 2015-01-24
    • 1970-01-01
    • 2015-07-22
    • 2015-08-24
    相关资源
    最近更新 更多