Несколько фильтров на коллекцию с angular-метеором

0

Я следую учебному курсу Meteor To-Do с Угловой интеграцией и изучаю фильтрацию коллекций. Я смог реализовать простой фильтр в коллекции для приложения, над которым я работаю, следуя принципам учебника, но теперь я застреваю, пытаясь понять, как добавить несколько запросов к фильтру.

В этом примере вы можете просмотреть неполные задачи, переключив флажок. Это реализовано в контроллере, наблюдая за $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. Теперь, если я хочу отфильтровать список дел неполными и приоритетными = $ scope.priority, я понимаю, что запрос Mongo должен быть чем-то вроде Tasks.find({ $and: [{ checked: {$ne: true} },{ priority: $scope.priority }]},{ sort: { createdAt: -1 } }).

В моем приложении я смог заставить двух наблюдателей правильно отслеживать изменения в двух переменных области видимости, аналогично моему примеру с $scope.hideCompleted и $scope.priority, но я не знаю, как сделать следующий шаг для слияния запросы при фильтрации коллекции. Я также немного потрудился с этим пакетом, так как в конечном итоге я надеюсь, что смогу фильтровать и сортировать по многим критериям, но я не зашел слишком далеко, прежде чем переключиться на описанные здесь концепции.

Я был бы признателен за любую помощь в этом. Спасибо!

Теги:
meteor
angular-meteor

2 ответа

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. $meteor.autorun будет срабатывать каждый раз, когда любые изменения getReactively изменяются.
  3. $scope.$meteorSubscribe и $scope.$meteorCollection предпочтительнее, поскольку они удаляют подписки и объект/коллекцию при уничтожении области.

Если у вас есть какие-либо проблемы, возможно, я смогу настроить демоверсию для вас.

  • 0
    Это выглядит довольно просто и выполняет то же самое в меньшем количестве строк. Я работаю с подпиской в другом месте контроллера, поэтому мне может потребоваться внести некоторые изменения, но я думаю, что я предпочту этот подход, поскольку он выполняет то же самое в меньшем количестве строк. Мне также нужно прочитать о $ meteorSubscribe и $ meteorCollection.
  • 0
    Удивительно, не стесняйтесь, чтобы начать новый вопрос, если вы застряли с настройками. Также, если вы не возражаете, отметьте правильные ответы, чтобы другим было легче их найти;)
Показать ещё 1 комментарий
0

Ну, я думаю, я был намного ближе, чем я ожидал, поэтому я отвечу на свой вопрос и расскажу, что я сделал, чтобы реализовать несколько фильтров в отношении гипотетического расширения приложения для работы.

Я сделал hideCompleted и priority переменные области видимости в свойствах объектной model и использовал один наблюдатель с аргументом true в конце, чтобы проверить равенство объекта (для любых изменений в 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}})
});
  • 0
    Вы строите все свои запросы на стороне клиента? Что произойдет, если я отредактирую ваш вызов Tasks.find? Убедитесь, что вы обрабатываете правила на стороне сервера
  • 0
    @Neil Не могли бы вы рассказать о том, что вы имеете в виду, отредактировав мой вызов Tasks.find и обработав правила на стороне сервера? Сейчас я использую варианты обоих ответов, но в любом случае на стороне сервера функции публикации у меня есть правила для запросов, сортировки и т. Д.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню