AngularJS不过滤产品列表

时间:2013-11-13 07:51:50

标签: javascript angularjs model-view-controller filtering

我在AngularJS过滤产品列表时遇到问题。我对我的变量做了一些console.log查询,看起来都很好。问题是视图不会更新以显示已过滤的产品。

当您在输入框中输入搜索文本时,过滤效果非常好,但在单击“类别”菜单项时它不起作用。

我想在用户点击菜单项时按类别过滤产品列表。

请参阅下面的代码,非常感谢任何帮助或建议。

我的app.js

myApp.controller('StoreController', function($scope, $filter, storeFactory, cartFactory) {
  $scope.cartTotal = 0;
  $scope.cartItems = [];
  $scope.categories = [];
  $scope.counted = 0;
  $scope.filteredProducts = {};

  //get the products
  storeFactory.getProducts(function(results) {
    $scope.products = results.products;
    $scope.counted = $scope.products.length;
    $scope.filteredProducts = results.products; 
  });

  $scope.$watch("search", function(query){
    if($scope.filteredProducts.length) { 
      $scope.filteredProducts = $filter("filter")($scope.products, query);
      $scope.counted = $scope.filteredProducts.length; 
    }
  });

  $scope.filterProductsByCategory = function(categoryName){
    console.log('category filter');
    /*$scope.products.forEach(function(o,i){
      console.log('filter');
      if( o.category_id !== categoryId ){
       $scope.filteredProducts.splice(i,1);
       console.log('removing');
       console.log(o);
      }
    });*/
    $scope.filteredProducts = $filter("filter")($scope.filteredProducts, categoryName);
    console.info('the filtered items');
    console.log($scope.filteredProducts);
    $scope.counted = $scope.filteredProducts.length;
  } 

  $scope.getCategories = function(){
    storeFactory.getCategories(function(results){
      $scope.categories = results.rows; 
    });
  }

      $scope.getCategories();
});

我的store.htm

更新: 我删除了额外的控制器引用并将所有内容包装在一个div中。

<div ng-controller="StoreController">

      <!-- the sidebar product menu -->
       <div class="block-content collapse in">
        <div class="daily" ng-repeat="category in categories | orderBy:'name'">
          <div class="accordion-group">
            <div ng-click="filterProductsByCategory(category.category_name)" class="accordion-toggle collapsed">{{category.category_name}}</div>
          </div>
        </div>
      </div>    
      </div>

      <!-- Load store items start -->
        <div class="label">Showing {{counted}} Product(s)</div> 
        <div class="row" ng-repeat="product in filteredProducts | orderBy:'product_name'" style="margin-left: 0px; width: 550px;">
          <hr></hr>
          <div class="span1" style="width: 120px;">

            <!--         <a data-toggle="lightbox" href="#carouselLightBox"> -->
            <a data-toggle="lightbox" href="#carouselLightBox{{product.product_id}}">
            <!--img alt={{ product.product_name }} ng-src="{{product.image}}" src="{{product.image}}" /-->
                <img id="tmp" class="" src="images/products/{{product.product_image_filename}}" alt=""></img>
            </a>
            <div class="lightbox hide fade" id="carouselLightBox{{product.product_id}}" style="display: none;">
              <div class='lightbox-content'>
                <img src="images/products/{{product.product_image_filename}}" alt="" />
                  <!--img alt={{ product.product_name }} ng-src="{{product.image}}" src="{{product.image}}" /-->
                  <button class="btn btn-primary" id="close_lightbox"  ng-click="closeBox(product.product_id, $event)">Close</button>
              </div>
                <style>
                  #close_lightbox
                  {
                    position: absolute;
                    top: 5px;
                    right: 5px;
                  }
                </style>
            </div>
          </div>

          <div class="span6" style="width: 330px; margin-bottom: 15px;">
            <h5 style="font-size: 14px; font-weight: bold;">{{product.product_name}}</h5>
            <p>{{product.product_description }}</p>
            <p>Category : {{product.category_name}}</p>
          </div>
          <div class="span3">
            <p class="price">Price : <strong>R{{ product.product_price }}</strong></p>
              </div>
        </div>

    <!-- end of controller -->
    </div>

2 个答案:

答案 0 :(得分:1)

侧栏使用StoreController的一个实例,主div使用另一个StoreController实例。每个实例都有自己的范围。应该使用相同的控制器实例:将所有内容包装在div中,并为此包装div使用唯一的StoreController。

答案 1 :(得分:1)

$scope.filteredProducts = {};

//get the products
storeFactory.getProducts(function (results) {
    $scope.products = results.products;
    $scope.counted = $scope.products.length;
    $scope.filteredProducts = results.products;
});

results.products是一个对象数组还是一个对象对象?因为$filter('filter')($scope.products,query);期望$scope.products是一个数组。

$scope.$watch("search", function (query) {
    if($scope.filteredProducts.length) {
        $scope.filteredProducts = $filter("filter")($scope.products, query);
        $scope.counted = $scope.filteredProducts.length;
    }
});

以下是我认为应该是这样的,你不需要$watch语句或filteredProducts数组/对象,在控制器中:

$scope.search = '';
$scope.products = [];
$scope.categories = ['category1','category2','category3'];

// assuming that your store function getProducts returns a promise here
storeFactory.getProducts().then(function(results){
    $scope.products = results.products; // needs to be an array of product objects
});

$scope.filterProductsByCategory = function(category){
    $scope.search = category;
};

然后在你的HTML Partial中,这不完全是你的,我只是以更短的形式向你展示可能的内容:

<button ng-repeat="cat in categories" ng-click="filterProductsByCategory(cat)">{{cat}}</button>

<div class="row" ng-repeat="product in products | filter:search | orderBy:'product_name'">
    <!-- Product Information Here -->
</div>

我创建了一个JSFiddle来演示:http://jsfiddle.net/mikeeconroy/QL28C/1/ 您可以使用任何术语进行表单搜索,也可以单击某个类别的按钮。