Я следую учебному курсу 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.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 } });
});
// });
});
Несколько вещей здесь:
autopublish
вы можете раскомментировать метод $scope.$meteorSubscribe
и заменить "yourSubscription"
на имя вашей фактической подписки.$meteor.autorun
будет срабатывать каждый раз, когда любые изменения getReactively
изменяются.$scope.$meteorSubscribe
и $scope.$meteorCollection
предпочтительнее, поскольку они удаляют подписки и объект/коллекцию при уничтожении области.Если у вас есть какие-либо проблемы, возможно, я смогу настроить демоверсию для вас.
Ну, я думаю, я был намного ближе, чем я ожидал, поэтому я отвечу на свой вопрос и расскажу, что я сделал, чтобы реализовать несколько фильтров в отношении гипотетического расширения приложения для работы.
Я сделал 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}})
});