0

我在使用 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();
});

我的商店.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>
4

2 回答 2

1

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

于 2013-11-13T07:57:13.813 回答
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 部分中,这不完全是您的,我只是在这里以较短的形式向您展示可能的情况:

<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/ 您可以使用任何术语进行自由形式搜索或单击类别的按钮。

于 2013-11-13T14:47:09.157 回答