问题
I have an ASP.NET MVC site with AngularJS on the Views and I need to do filtering on a list based on certain controls using AngularJS. Here are the controls:
An input textbox acting as a search but serves as the angular model for the list. Currently the list is in format, however I plan to change this to divs.
A list (for now as it will be divs later) bound to the input search box (an ng-model), but also filtered to handle pagination based on the search box.
An Angular Bootstrap UI Pagination control managing the pagination for the search box but also for the slider.
A custom Angular slider that should (as this is the issue now) that should filter the list based on the price component.
Currently the list is fed via http ajax call from Angular that populates a list of JSON objects with many properties. The list is currently filtered from the input search box through the Location property on the JSON object (although it automatically does this as you type, it finds the location property and filters on that - I'm puzzled as to how since I'm new to AngularJS because I haven't explicitly told it to filter on the Location property).
The issue is that I would also like it to filter the list based on the Price property on the JSON object. In my code I've made an attempt to do this by custom filters and watches but none of it seems to work. I also want the pagination to be updated as the list narrows down as it does for the input search box.
So the list must be filtered by the input search box and also by the slider (and possibly checkboxes or drop downs if I plan to update it later, but for now the list is filtered by just the price slider and input search box).
Here is my code:
HTML
<div data-ng-app="dealsPage">
<input type="text" data-ng-model="cityName" />
<div data-ng-controller="DestinationController">
<ul>
<li data-ng-repeat="deals in destinations | startFrom:(currentPage - 1)*pageSize | limitTo:pageSize | priceSorter:curLow:curHigh">{{deals.Location}} -- {{deals.Price}}</li>
</ul>
<br />
<pagination rotate="true" num-pages="noOfPages" current-page="currentPage" max-size="maxSize" class="pagination-small" boundary-links="true"></pagination>
<br />
<slider min="{{min}}" max="{{max}}" low="curLow" high="curHigh" round="2" step="0.25" translate="translate(val)"></slider>
<br />
Value: {{curLow}} -- {{curHigh}}
<br />
Range: {{range}}
</div>
AngularJS
var destApp = angular.module('dealsPage', ['ui.bootstrap']);
var sliderDirective;
destApp.controller('DestinationController', function ($scope, $http, $filter) {
$scope.destinations = {};
$scope.filteredDestinations = {};
$scope.min = 300;
$scope.max = 1000;
$scope.curLow = 320;
$scope.curHigh = 980;
$scope.translate = function (val) { return val + "° C"; };
$scope.range = 0;
$http.get('/Deals/GetDeals').success(function (data) {
$scope.destinations = data;
});
$scope.pageSize = 10;
$scope.maxSize = 5;
//Watch for pagination based on the input search box.
$scope.$watch('cityName', function (newCityName) {
$scope.currentPage = 1;
$scope.filteredDestinations = $filter('filter')($scope.destinations, $scope.cityName);
$scope.noOfPages = isNaN($scope.filteredDestinations.length / 10) ? 200 : $scope.filteredDestinations.length / 10;
});
//These two watches are for the slider controls to observe pagination, but should I use the list filtereing logic in here and how?
$scope.$watch('curLow', function (newValue) {
$scope.range = Math.round($scope.curHigh - newValue);
$scope.filteredDestinations = $filter('filter')($scope.destinations, $scope.range);
$scope.noOfPages = isNaN($scope.filteredDestinations.length / 10) ? 200 : $scope.filteredDestinations.length / 10;
});
$scope.$watch('curHigh', function (newValue) {
$scope.range = Math.round(newValue - $scope.curLow);
$scope.filteredDestinations = $filter('filter')($scope.destinations, $scope.range);
$scope.noOfPages = isNaN($scope.filteredDestinations.length / 10) ? 200 : $scope.filteredDestinations.length / 10;
});});
destApp.directive('slider', function ($timeout, $compile)....//Code for slider here);
destApp.filter('startFrom', function () {
return function (input, start) {
start = +start; //parse to int
return input.slice(start);
};
});
destApp.filter('priceSorter', function () {
var filteredInput = new Array();
return function (input, curLow, curHigh) {
for (var x = 0; x <= input.length; x++) {
if ((input[x].Price > curLow) && (input[x].Price < curHigh)) {
filteredInput.push(input[x]);
}
}
//This should work as I can see the filtering taking place, but the list does not get rendered on the view!
return filteredInput;
};});
I thought of making the slider an ng-model as well because I want it to filter on the ul list by the Price property but I don't know how to make a slider an ng-model.
In any case, I get the feeling that filtering is the way to go here as my custom filter does get invoked and I'm able to do my custom logic as shown, but the new array is not rendered after the changes have been filtered.
Thanks very much,
Ben.
来源:https://stackoverflow.com/questions/18722246/list-filtering-not-working-in-angularjs-when-bound-to-a-slider-with-pagination