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

更新: 余分なコントローラー参照を削除し、すべてを 1 つの 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 の 1 つのインスタンスを使用しており、メイン 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 に答える