用angular js过滤项目


Filtering items with angular js

我有一个服务形式的项目数组-据我所知,这是在不同控制器中保存数据的正确方法。我看了教程,并按品牌进行了过滤。但是我在通过其他参数过滤商品时遇到了一个障碍,比如价格、长度和频率……所以我通过另一个例子制作了滑块,但我不知道如何将它与我的项目数组联系起来。请帮我一个忙,告诉我如何捆绑我的一个参数,例如价格。

http://angular.zxcvbn.ru

services.js:

myApp.service('ProductDataService', function() {
    //sample data
    var items = [
        { name:'Picachoo',        id:1, price:25000, pict:'http://www.metrord.do/_internal/gxml!0/2qijkhn0ctpwx8acoz5fxkpvtmr4nbh$r05jcw5nnz5dt1u7odn7q01jm5k3ezo/screen-shot-2016-07-24-at-11-55-41-am.jpeg',       len: 250,  friq: 5000,  brand: 'came' },
        { name:'Tortule',        id:2, price:30000, pict:'https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcR2APj6_uBfhHRXLn1dZN58ZocpzMxGMFLZmuqHEU5SybKN4QAVfg',       len: 250,  friq: 300,   brand: 'came' },
        { name:'Dragon',        id:3, price:33500, pict:'https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcSJotIxkjgXgm9m3m-0FuUxN6g9fGGXmP84VDRrPZoWa-x8Dqqd',       len: 350,  friq: 300,   brand: 'came' },
        { name:'encrypted1',        id:4, price:45000, pict:'http://gaidi.ru/wp-content/uploads/2016/07/kak-pravilno-lovit-pokemonov-v-pokemon-go.jpg',       len: 400,  friq: 3000,  brand: 'came' },
        { name:'pravilno',        id:5, price:48600, pict:'http://vignette3.wikia.nocookie.net/pokemon/images/2/2e/009Blastoise_Dream.png/revision/latest?cb=20140812050618',       len: 550,  friq: 2000,  brand: 'came' },
        { name:'images',       id:6, price:30000, pict:'https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcSqywi0lMtmf1sAR-20rg0HXETMueY3H71iJP35WsdsPHGVokK41g',       len: 550,  friq: 1000,  brand: 'bft'  },
        { name:'Foxy',       id:7, price:38000, pict:'http://vgtimes.ru/uploads/posts/2016-07/1468938437_pk_vulpix.png',       len: 350,  friq: 10000, brand: 'bft'  },
        { name:'Pteradactys', id:8, price:43000, pict:'https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcRJBXypwhl8-z4IsAZokgQlqPx_vZymtENBdlPy1HhN34uODEZ5',       len: 800,  friq: 10000, brand: 'bft'  },
        { name:'encrypted',              id:9, price:35800, pict:'https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcQZNKoA9LMtQHhgU4Toy7xXfzGEp6Rb4Kv6I16RgMjWO0Dnb36EFA',       len: 1200, friq: 3000,  brand: 'faac' },
        { name:'Jidjfj',                  id:10, price:14000, pict:'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRPBKrRLvhYm9y-LxwRM4Qc_psMjd_luij_04ChmmQjcrdxgmcG3w',       len: 800,  friq: 5000,  brand: 'fors' }
        ];
    brands = {came : true, bft : true, faac : true,  fors : true} ;


    this.getItems = function() {
      return items;
    };
    this.getBrands = function() {
      return brands;
    };
    this.maxPrice = function() {
    var max;
    var producto;
    for(var i = 0; i < items.length-1; i++) {
       for(var j = 0; j < items.length-i-1; j++){
          if (producto[j] > producto[j+1]) {
          max = producto[j];
          producto[j] = producto[j+1];
          producto[j+1] = b;
                                            }
                                                }
                                            }
    return max;
                                   }
    this.minPrice = function() {
    var min;
    var producto;
    for(var i = 0; i < items.length-1; i++) {
       for(var j = 0; j < items.length-i-1; j++){
          if (producto[j] < producto[j+1]) {
          min = producto[j];
          producto[j] = producto[j+1];
          producto[j+1] = b;
                                            }
                                                }
                                            }
    return min;
                                   }
  });

slider_price.js:

myApp.controller('priceCtrl', function($scope, ProductDataService) {
  $scope.search = { price_min : '', price_max : '', amount_min : 14000, amount_max : 48600 };
});
/* Range Slider
    Input with default values:
    -min=0      // Min slider value
    -max=100    // Max slider value
    -step=1     // Steps
    Output / Input model
    -value-min    // Default value @min
    -value-max    // Default value @max
    example:
    <slider-range min="0" max="100" step="5" value-min="scope.form.slider_value_min" value-max="scope.form.slider_value_max"></slider-range>
*/
myApp.directive('priceRange', ['$document',function($document) {
// Move slider handle and range line
  var moveHandle = function(handle, elem, posX) {
    $(elem).find('.handle.'+handle).css("left",posX +'%');
  };
  var moveRange = function(elem,posMin,posMax) {
    $(elem).find('.range').css("left",posMin +'%');
    $(elem).find('.range').css("width",posMax - posMin +'%');
  };
return {
    template: '<div class="slider horizontal">'+
                '<div class="range"></div>'+
                '<a class="handle min" ng-mousedown="mouseDownMin($event)"></a>'+
                '<a class="handle max" ng-mousedown="mouseDownMax($event)"></a>'+
              '</div>',
    replace: true,
    restrict: 'E',
    scope:{
      valueMin:"=",
      valueMax:"="
    },
    link: function postLink(scope, element, attrs) {
        // Initilization
        var dragging = false;
        var startPointXMin = 0;
        var startPointXMax = 0;
        var xPosMin = 0;
        var xPosMax = 0;
        var settings = {
                "min"   : (typeof(attrs.min) !== "undefined"  ? parseInt(attrs.min,10) : 0),
                "max"   : (typeof(attrs.max) !== "undefined"  ? parseInt(attrs.max,10) : 100),
                "step"  : (typeof(attrs.step) !== "undefined" ? parseInt(attrs.step,10) : 1)
            };
        if ( typeof(scope.valueMin) == "undefined" || scope.valueMin === '' ) 
            scope.valueMin = settings.min;
        if ( typeof(scope.valueMax) == "undefined" || scope.valueMax === '' ) 
            scope.valueMax = settings.max;
        // Track changes only from the outside of the directive
        scope.$watch('valueMin', function() {
          if (dragging) return;
          xPosMin = ( scope.valueMin - settings.min ) / (settings.max - settings.min ) * 100;
          if(xPosMin < 0) {
              xPosMin = 0;
          } else if(xPosMin > 100)  {
              xPosMin = 100;
          }
          moveHandle("min",element,xPosMin);
          moveRange(element,xPosMin,xPosMax);
        });
        scope.$watch('valueMax', function() {
          if (dragging) return;
          xPosMax = ( scope.valueMax - settings.min ) / (settings.max - settings.min ) * 100;
          if(xPosMax < 0) {
              xPosMax = 0;
          } else if(xPosMax > 100)  {
              xPosMax = 100;
          }
          moveHandle("max",element,xPosMax);
          moveRange(element,xPosMin,xPosMax);
        });
        // Real action control is here
        scope.mouseDownMin = function($event) {
            dragging = true;
            startPointXMin = $event.pageX;
            // Bind to full document, to make move easiery (not to lose focus on y axis)
            $document.on('mousemove', function($event) {
                if(!dragging) return;
                //Calculate handle position
                var moveDelta = $event.pageX - startPointXMin;
                xPosMin = xPosMin + ( (moveDelta / element.outerWidth()) * 100 );
                if(xPosMin < 0) {
                    xPosMin = 0;
                } else if(xPosMin > xPosMax) {
                  xPosMin = xPosMax;
                } else {
                    // Prevent generating "lag" if moving outside window
                    startPointXMin = $event.pageX;
                }
                scope.valueMin = Math.round((((settings.max - settings.min ) * (xPosMin / 100))+settings.min)/settings.step ) * settings.step;
                scope.$apply();
                // Move the Handle
                moveHandle("min", element,xPosMin);
                moveRange(element,xPosMin,xPosMax);
            });
        $document.mouseup(function(){
                dragging = false;
                $document.unbind('mousemove');
                $document.unbind('mousemove');
            });
        };
        scope.mouseDownMax = function($event) {
            dragging = true;
            startPointXMax = $event.pageX;
            // Bind to full document, to make move easiery (not to lose focus on y axis)
            $document.on('mousemove', function($event) {
                if(!dragging) return;
                //Calculate handle position
                var moveDelta = $event.pageX - startPointXMax;
                xPosMax = xPosMax + ( (moveDelta / element.outerWidth()) * 100 );
                if(xPosMax > 100)  {
                    xPosMax = 100;
                } else if(xPosMax < xPosMin) {
                  xPosMax = xPosMin;
                } else {
                    // Prevent generating "lag" if moving outside window
                    startPointXMax = $event.pageX;
                }
                scope.valueMax = Math.round((((settings.max - settings.min ) * (xPosMax / 100))+settings.min)/settings.step ) * settings.step;
                scope.$apply();
                // Move the Handle
                moveHandle("max", element,xPosMax);
                moveRange(element,xPosMin,xPosMax);
            });
            $document.mouseup(function(){
                dragging = false;
                $document.unbind('mousemove');
                $document.unbind('mousemove');
            });
        };
    }
  };
}]);

app.js:

var myApp = angular.module("filterApp", []);
myApp.controller('ExampleController', ['$scope', '$window', function($scope, $window) {
      $scope.greeting = 'Hello, World!';
      $scope.doGreeting = function(greeting) {
        $window.alert(greeting);
      };
    }]);
myApp.controller('coolCtrl', function($scope) {
      $scope.whoAmI = function(){
        console.log("This is whoAmI function in the coolCtrl!");
    };
});
myApp.controller('mainCtrl', function($scope, ProductDataService){
  $scope.helloWorld = function(){
    console.log("This is helloWorld function in the mailCtrl!");
  };
  $scope.items = ProductDataService.getItems();
  $scope.brands = ProductDataService.getBrands();
  $scope.refresh = function(){
    location.reload();
  };
  $scope.showPopUpMsg = false;
  $scope.openPopUp = function( text ) {
  $scope.showPopUpMsg = true;
  $scope.popUpMsgContent = text;
  $scope.minimun = 123;
  };
});

jilters.js:

myApp.filter('brandsfilter', function () {
  return function(input, filter) {
    var result = [];
    angular.forEach(input, function (item) {
        angular.forEach(filter, function (isfiltered, brand) {
            if (isfiltered && brand === item.brand) {
                result.push(item);
            }
        });
    });
    return result;
  };
});

index . php:

<?php
require 'scripts/mail_script.php';
?>
<!doctype html>
<html class="no-js" lang="">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="apple-touch-icon" href="apple-touch-icon.png">
        <!-- Place favicon.ico in the root directory -->
        <link rel="stylesheet" href="styles/normalize.css">
        <link rel="stylesheet" href="styles/main.css">
        <link rel="stylesheet" href="styles/bootstrap.css">
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <!-- for slider work -->
    </head>
    <body ng-app="filterApp" ng-controller='mainCtrl'>

        <!--[if lt IE 8]>
            <p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
        <![endif]-->

        <!-- Add your site or application content here -->
<div class="container">
<section class='top' >

<h1>Filter</h1>
      <!-- //// http://embed.plnkr.co/woqn3i/ /// -->

   <!-- ///////// -->
<div class="row" id='items'>
<div>
  <div class="col-md-4" ><h2>params:</h2>
  <div ng-controller="priceCtrl">
    <p>Choose price:</p>
    <p>min: <input type="number" ng-model="search.amount_min"/> $</p>
    <p>max: <input type="number" ng-model="search.amount_max"/> $</p>
    <slider-range min="14000" max="48600" step="100" value-min="search.amount_min" value-max="search.amount_max"></slider-range>
</div>
    <hr>
  <p>По названию:</p>
  <p><input type="text" ng-model="price" /></p>
    <p>Brand:</p>
  <ul >
  <li ng-repeat="(brand, value) in brands">
    <input type="checkbox" ng-model="brands[brand]" /> {{brand}}
  </li>
  </ul>
   <hr>
      <!-- //// http://embed.plnkr.co/woqn3i/ /// -->
<div ng-controller="filterCtrl">
    <p>length:</p>
    <p>От: <input type="text" ng-model="search.price_min"/> meters</p>
    <p>До: <input type="text" ng-model="search.price_max"/> meters</p>
    <slider-range min="2.5" max="12" value-min="search.price_min" value-max="search.price_max"></slider-range>
    <hr>
    <p>friquincy:</p>
    <p>Min: <input type="number" ng-model="search.amount_min"/> times</p>
    <p>Max: <input type="number" ng-model="search.amount_max"/> times</p>
    <slider-range min="300" max="10000" step="100" value-min="search.amount_min" value-max="search.amount_max"></slider-range>
    </div>
    <hr>
   <!-- ///////// -->
    <div class="actions"/>
        <input type="button" value="Сбросить" ng-click='refresh()'>
    </div>

  </div>
  <div class="col-md-8"><h2>______ kinds</h2>
  <?php
    if($success) echo '<h4 class="bg-success text-center">'.'Сообщение отправлено!' . '</h4>';
    if($error_message) echo '<h4 class="bg-danger text-center">'.'Сообщение не отправлено:' . $error_message. '</h4>';
  ?>

  <div class="row">
    <!-- LOOP.-->
    <div ng-repeat="item in items | filter:price | orderBy:price | brandsfilter:brands ">
    <div class="col-md-4 col-sm-6 col-sx-12">
        <div class="item-inner">
<div class="image-product">
  <div class="caption">
    <div class="box-view">
    <div class="name"><a href="" data-toggle="modal" data-target="#myModal{{item.id}}">{{item.name}}</a></div>
  </div>
  </div>
    <img src="{{item.pict}}" alt="{{item.name}}" title="{{item.name}}" class="img-responsive">
    <p class="price"><span class="price">Price: {{item.price}} $.</span></p>
    <p class="description">{{item.name}} - just another piece of information, first preporty is {{item.len}} m. <br>another is: {{item.friq}} per day. </p>
</div>
</div>
</div><!-- col -->
    </div>  <!-- ng-repeat -->
</div>  <!-- row -->
</div>
</div>  <!-- mainCtrl -->
</section>

</div>
  <div class="panel-footer">
        <script src="vendor/angular.js"></script>
        <script src="scripts/app.js"></script>
        <script src="scripts/services.js"></script>
        <script src="scripts/filters.js"></script>
        <script src="scripts/slider.js"></script>
        <script src="scripts/slider_price.js"></script>
        <script src="vendor/jquery.js"></script>
        <script src="vendor/bootstrap.js"></script>

        <!-- Google Analytics: change UA-XXXXX-X to be your site's ID. -->
</div>
    </body>
</html>

AngularJS内置的filter已经支持多个关键字过滤器,你只需要实现comparator功能来满足你的需求。

首先,将模板中的过滤器更改为
<div ng-repeat="item in items | filter:myFilters:myComparator | orderBy:price">

然后在你的filterCtrl中你需要定义myFiltersmyComparator

$scope.myFilters = {price: 4000, brand: 'abc'};
$scope.myComparator = function(actual, expected) {
    if (actual == parseInt(actual)) {
        return actual > expected;
    }
    else {
        return actual == expected;
    }
}

myComparator中,你可以自定义你想要过滤它的方式(精确匹配,算术比较或部分匹配,只要记住返回布尔值

只要更新$scope.myFilters每当你的过滤器关键字改变,结果将在下一个摘要周期更新。