【问题标题】:angularjs filter (not working)angularjs过滤器(不工作)
【发布时间】:2023-03-04 13:14:01
【问题描述】:

以下 HTML、Javascript 和 JSON 正确呈现,但过滤器根本不起作用。我们做错了什么?

<div data-ng-controller="dashboard_controller">
    <h1>
        Catalogs
        <input type="text" data-ng-model="catalog_filter" placeholder="Filter Distributors">
    </h1>

    <div class="catalogs_listing">
        <ul data-ng-repeat="catalog in catalogs | filter:catalog_filter">
            <li><a href="{{catalog.distributor_id}}/d/products/catalog_view/{{catalog.uid}}">
                <div class="catalog_thumb">
                    <div class="catalog_thumb_image">
                        <img src="{{catalog.thumb_image}}" />
                    </div>
                </div>
                <div class="catalog_info">
                    <h2>{{distributors[catalog.distributor_id].name}}
                        <span>{{catalog.products_count}}p</span>
                    </h2>
                    <p>{{catalog.name}}</p>
                </div>
                </a>
            </li>
        </ul>
    </div>
</div>

Javascript:

app.controller('dashboard_controller', function ($scope, $http) {
    $http.get('./api/distributors/my').then(function (res) {
        $scope.distributors = res.data;
    });
    $http.get('./api/dashboard/catalogs').then(function (res) {
        $scope.catalogs = res.data;
    });
});

还有这 2 个 JSON:

api/distributors/my:

{
    "data": {
        "9kkE1sL8vXSZMVaL": {
            "created": "1346840145.22",
            "uid": "9kkE1sL8vXSZMVaL",
            "created_by": "3W7AoIQHTtvPauaK",
            "name": "Nikee",
            "description": "Just do it",
            "image_file": "LogoNike.jpg",
            "modified": "1368443518.3894",
            "modified_by": "3W7AoIQHTtvPauaK",
            "currency": "gbp"
        },
        "1OBKUhpb8srwHVVb": {
            "created": "1346840213.41",
            "uid": "1OBKUhpb8srwHVVb",
            "created_by": "3W7AoIQHTtvPauaK",
            "name": "Zappos",
            "description": "The webs most popular shoe store",
            "image_file": "zappos.jpg",
            "modified": "1347006513.93",
            "modified_by": "3W7AoIQHTtvPauaK",
            "currency": null
        },
        "qHPXDp5lSQuz9z3Q": {
            "created": "1346840305.78",
            "uid": "qHPXDp5lSQuz9z3Q",
            "created_by": "3W7AoIQHTtvPauaK",
            "name": "Kitchenaid",
            "description": "For the way it's made",
            "image_file": "kitchenaid_logo.gif",
            "modified": "1346840305.78",
            "modified_by": "3W7AoIQHTtvPauaK",
            "currency": null
        },
        "9K4G8gE1sh4qpVG2": {
            "created": "1346840443.32",
            "uid": "9K4G8gE1sh4qpVG2",
            "created_by": "3W7AoIQHTtvPauaK",
            "name": "Unilever",
            "description": "Create a better future",
            "image_file": "Unilever-logo.jpg",
            "modified": "1346842125.2",
            "modified_by": "3W7AoIQHTtvPauaK",
            "currency": null
        },
        "55ORaD7h0EMcaX82": {
            "created": "1346840529.93",
            "uid": "55ORaD7h0EMcaX82",
            "created_by": "3W7AoIQHTtvPauaK",
            "name": "Dell",
            "description": "The power to do more",
            "image_file": "dell-logo.jpg",
            "modified": "1346840529.93",
            "modified_by": "3W7AoIQHTtvPauaK",
            "currency": null
        },
        "2LHf5ZipYjA2PdXu": {
            "created": "1352084334.37",
            "uid": "2LHf5ZipYjA2PdXu",
            "created_by": "3MO4JyiB9rMWTfBu",
            "name": "Online Retailer",
            "description": "Online Retailer",
            "image_file": "Home and Giftware.gif",
            "modified": "1352954806.28",
            "modified_by": "cu3OraVD7WclpLrX",
            "currency": null
        },
        "MdTDL72ynFySuUCR": {
            "created": "1352870158.83",
            "uid": "MdTDL72ynFySuUCR",
            "created_by": "1JiAF71w5VPHGgJe",
            "name": "Uniuniform",
            "description": "Uniform Suppliers",
            "image_file": "CWLogo.png",
            "modified": "1358317144.85",
            "modified_by": "sv3HuiiRbiuHWkul",
            "currency": null
        },
        "oyYmdDcod9fseZng": {
            "created": "1352934703.42",
            "uid": "oyYmdDcod9fseZng",
            "created_by": "cu3OraVD7WclpLrX",
            "name": "Heidy Pharmaceuticals",
            "description": "Pharmaceutical Solutions",
            "image_file": "heidy.jpg",
            "modified": "1352934703.43",
            "modified_by": "cu3OraVD7WclpLrX",
            "currency": null
        },
        "Kfs4HdFUfz6j2l2I": {
            "created": "1352953682.22",
            "uid": "Kfs4HdFUfz6j2l2I",
            "created_by": "cu3OraVD7WclpLrX",
            "name": "xxx",
            "description": "Online Retailer",
            "image_file": "xxx.gif",
            "modified": "1352953828.34",
            "modified_by": "cu3OraVD7WclpLrX",
            "currency": null
        },
        "g2qRqUWvPSLRvLQr": {
            "created": "1352953924.68",
            "uid": "g2qRqUWvPSLRvLQr",
            "created_by": "cu3OraVD7WclpLrX",
            "name": "ddd",
            "description": "Natural Product Retailer",
            "image_file": "yes-to.jpg",
            "modified": "1352953924.68",
            "modified_by": "cu3OraVD7WclpLrX",
            "currency": null
        },
        "bbSu3jpFhdkG3TJR": {
            "created": "1352954016.22",
            "uid": "bbSu3jpFhdkG3TJR",
            "created_by": "cu3OraVD7WclpLrX",
            "name": "llll",
            "description": "Artificial Product Retailer",
            "image_file": "l.jpg",
            "modified": "1352954016.23",
            "modified_by": "cu3OraVD7WclpLrX",
            "currency": null
        },
        "X9xWF9VrRDqGWZ6S": {
            "created": "1352954722.97",
            "uid": "X9xWF9VrRDqGWZ6S",
            "created_by": "cu3OraVD7WclpLrX",
            "name": "zzz",
            "description": "Toy Manufacturer",
            "image_file": "zzz.jpg",
            "modified": "1352954722.97",
            "modified_by": "cu3OraVD7WclpLrX",
            "currency": null
        },
        "02CCPuWtM6ZJVgiQ": {
            "created": "1367741881.7113",
            "uid": "02CCPuWtM6ZJVgiQ",
            "created_by": "3W7AoIQHTtvPauaK",
            "name": "test brand",
            "description": "xxxx",
            "image_file": null,
            "modified": "1367741882.5129",
            "modified_by": "3W7AoIQHTtvPauaK",
            "currency": null
        },
        "GjsdgMCzp1n379j0": {
            "created": "1369136484.1802",
            "uid": "GjsdgMCzp1n379j0",
            "created_by": "3W7AoIQHTtvPauaK",
            "name": "testing all products",
            "description": "just a test",
            "image_file": null,
            "modified": "1369136484.5298",
            "modified_by": "3W7AoIQHTtvPauaK",
            "currency": "usd"
        },
        "spVsxtJVroMkXQ1N": {
            "created": "1370508658.353",
            "uid": "spVsxtJVroMkXQ1N",
            "created_by": "3W7AoIQHTtvPauaK",
            "name": "pppp Import",
            "description": "",
            "image_file": null,
            "modified": "1370508658.4394",
            "modified_by": "3W7AoIQHTtvPauaK",
            "currency": "usd"
        }
    }

api/仪表板/目录

{
    "data": {
        "UPf17vFhMhiM2yYl": {
            "created": "1352960014.4",
            "uid": "UPf17vFhMhiM2yYl",
            "created_by": "3MO4JyiB9rMWTfBu",
            "name": "All Products",
            "description": "This catalog contains all of your products",
            "modified": "1352960014.4",
            "modified_by": "3MO4JyiB9rMWTfBu",
            "distributor_id": "9kkE1sL8vXSZMVaL",
            "image": null,
            "start": null,
            "end": null,
            "is_archived": null,
            "products_count": "0",
            "thumb_image": "resources/media/default_image.jpg.thumbs/165x165.jpg"
        },
        "ZUfcKpz0VrJZZZvW": {
            "created": "1354172792.79",
            "uid": "ZUfcKpz0VrJZZZvW",
            "created_by": "ORIGWlEFxbuE945J",
            "name": "test catalog",
            "description": "",
            "modified": "1354172792.79",
            "modified_by": "ORIGWlEFxbuE945J",
            "distributor_id": "9kkE1sL8vXSZMVaL",
            "image": null,
            "start": null,
            "end": null,
            "is_archived": null,
            "products_count": "0",
            "thumb_image": "resources/media/default_image.jpg.thumbs/165x165.jpg"
        },
        "6YoSSDCzLH8gEokf": {
            "created": "1360706477.5283",
            "uid": "6YoSSDCzLH8gEokf",
            "created_by": "3W7AoIQHTtvPauaK",
            "name": "xxxx",
            "description": "",
            "modified": "1360706477.5312",
            "modified_by": "3W7AoIQHTtvPauaK",
            "distributor_id": "9kkE1sL8vXSZMVaL",
            "image": null,
            "start": null,
            "end": null,
            "is_archived": null,
            "products_count": "3",
            "thumb_image": "resources/media/default_image.jpg.thumbs/165x165.jpg"
        },
        "4AwqE7iTNQmjSBED": {
            "created": "1360794567.8451",
            "uid": "4AwqE7iTNQmjSBED",
            "created_by": "3W7AoIQHTtvPauaK",
            "name": "All Products",
            "description": null,
            "modified": "1360794567.8454",
            "modified_by": "3W7AoIQHTtvPauaK",
            "distributor_id": "4AwqE7iTNQmjSBED",
            "image": null,
            "start": null,
            "end": null,
            "is_archived": null,
            "products_count": "1",
            "thumb_image": "resources/media/default_image.jpg.thumbs/165x165.jpg"
        },
        "02CCPuWtM6ZJVgiQ": {
            "created": "1367741881.7916",
            "uid": "02CCPuWtM6ZJVgiQ",
            "created_by": "3W7AoIQHTtvPauaK",
            "name": "All Products",
            "description": null,
            "modified": "1367741881.7919",
            "modified_by": "3W7AoIQHTtvPauaK",
            "distributor_id": "02CCPuWtM6ZJVgiQ",
            "image": null,
            "start": null,
            "end": null,
            "is_archived": null,
            "products_count": "2095",
            "thumb_image": "resources/media/default_image.jpg.thumbs/165x165.jpg"
        },
        "9kkE1sL8vXSZMVaL": {
            "created": "1368165852.0352",
            "uid": "9kkE1sL8vXSZMVaL",
            "created_by": "3W7AoIQHTtvPauaK",
            "name": "All Products",
            "description": null,
            "modified": "1368165852.0361",
            "modified_by": "3W7AoIQHTtvPauaK",
            "distributor_id": "9kkE1sL8vXSZMVaL",
            "image": null,
            "start": null,
            "end": null,
            "is_archived": null,
            "products_count": "26",
            "thumb_image": "resources/media/default_image.jpg.thumbs/165x165.jpg"
        },
        "ZmSiqOK2C2Sq3MWB": {
            "created": "1368958571.9548",
            "uid": "ZmSiqOK2C2Sq3MWB",
            "created_by": "3W7AoIQHTtvPauaK",
            "name": "Test Catalog",
            "description": "",
            "modified": "1368958571.9581",
            "modified_by": "3W7AoIQHTtvPauaK",
            "distributor_id": "02CCPuWtM6ZJVgiQ",
            "image": null,
            "start": "0",
            "end": "0",
            "is_archived": "1",
            "products_count": "0",
            "thumb_image": "resources/media/default_image.jpg.thumbs/165x165.jpg"
        },
        "flzoMbizDDTDpjgc": {
            "created": "1368958778.8623",
            "uid": "flzoMbizDDTDpjgc",
            "created_by": "3W7AoIQHTtvPauaK",
            "name": "xzczxc",
            "description": "",
            "modified": "1368958778.8637",
            "modified_by": "3W7AoIQHTtvPauaK",
            "distributor_id": "02CCPuWtM6ZJVgiQ",
            "image": null,
            "start": "0",
            "end": "0",
            "is_archived": "0",
            "products_count": "29",
            "thumb_image": "resources/media/default_image.jpg.thumbs/165x165.jpg"
        },
        "KfRJHxp7jBnBGCJ5": {
            "created": "1369219487.4418",
            "uid": "KfRJHxp7jBnBGCJ5",
            "created_by": "3W7AoIQHTtvPauaK",
            "name": "hhh",
            "description": "",
            "modified": "1369219487.4433",
            "modified_by": "3W7AoIQHTtvPauaK",
            "distributor_id": "9kkE1sL8vXSZMVaL",
            "image": null,
            "start": "0",
            "end": "0",
            "is_archived": "0",
            "products_count": "7",
            "thumb_image": "resources/media/default_image.jpg.thumbs/165x165.jpg"
        },
        "spVsxtJVroMkXQ1N": {
            "created": "1370508658.3567",
            "uid": "spVsxtJVroMkXQ1N",
            "created_by": "3W7AoIQHTtvPauaK",
            "name": "All Products",
            "description": null,
            "modified": "1370508658.3575",
            "modified_by": "3W7AoIQHTtvPauaK",
            "distributor_id": "spVsxtJVroMkXQ1N",
            "image": null,
            "start": "0",
            "end": "0",
            "is_archived": "0",
            "products_count": "343",
            "thumb_image": "resources/media/default_image.jpg.thumbs/165x165.jpg"
        },
        "1OBKUhpb8srwHVVb": {
            "created": "1370857435.5606",
            "uid": "1OBKUhpb8srwHVVb",
            "created_by": "3W7AoIQHTtvPauaK",
            "name": "All Products",
            "description": null,
            "modified": "1370857435.5612",
            "modified_by": "3W7AoIQHTtvPauaK",
            "distributor_id": "1OBKUhpb8srwHVVb",
            "image": null,
            "start": "0",
            "end": "0",
            "is_archived": "0",
            "products_count": "4",
            "thumb_image": "resources/media/default_image.jpg.thumbs/165x165.jpg"
        },
        "wXMHFdPyiXFBuRjJ": {
            "created": "1370864864.1247",
            "uid": "wXMHFdPyiXFBuRjJ",
            "created_by": "3W7AoIQHTtvPauaK",
            "name": "x",
            "description": "",
            "modified": "1370864864.1278",
            "modified_by": "3W7AoIQHTtvPauaK",
            "distributor_id": "spVsxtJVroMkXQ1N",
            "image": null,
            "start": "0",
            "end": "0",
            "is_archived": "0",
            "products_count": "10",
            "thumb_image": "resources/media/default_image.jpg.thumbs/165x165.jpg"
        },
        "GjsdgMCzp1n379j0": {
            "created": "1371116610.6898",
            "uid": "GjsdgMCzp1n379j0",
            "created_by": "3W7AoIQHTtvPauaK",
            "name": "All Products",
            "description": null,
            "modified": "1371116610.6902",
            "modified_by": "3W7AoIQHTtvPauaK",
            "distributor_id": "GjsdgMCzp1n379j0",
            "image": null,
            "start": "0",
            "end": "0",
            "is_archived": "0",
            "products_count": "2095",
            "thumb_image": "resources/media/default_image.jpg.thumbs/165x165.jpg"
        },
        "gvWLNWwsI3B7mnCU": {
            "created": "1371116669.5872",
            "uid": "gvWLNWwsI3B7mnCU",
            "created_by": "3W7AoIQHTtvPauaK",
            "name": "All Products",
            "description": null,
            "modified": "1371116669.5877",
            "modified_by": "3W7AoIQHTtvPauaK",
            "distributor_id": "gvWLNWwsI3B7mnCU",
            "image": null,
            "start": "0",
            "end": "0",
            "is_archived": "0",
            "products_count": 0,
            "thumb_image": "resources/media/default_image.jpg.thumbs/165x165.jpg"
        }
    }

【问题讨论】:

  • 我会尝试的第一件事是在分配完成语句 $scope.catalogs = res.data; 之后的目录回调中执行 $scope.$apply()
  • 我看到的一件事是 ng-repeat 数据不是一个数组,而是一个具有命名键的对象。这可能会混淆过滤器。另见评论:stackoverflow.com/questions/16390151/…
  • 您希望使用哪些属性来过滤?您的文件管理器占位符表明您希望按发行商名称进行过滤,对吧?
  • @Narretz - 请留下此评论作为答案,以便我接受。
  • 这个答案在另一个线程中节省了我的时间:stackoverflow.com/a/14733280/4865619

标签: javascript json angularjs


【解决方案1】:

Angular 过滤器无法将对象的对象作为输入处理。 ng-repeat 可以渲染它们,但过滤器需要一个对象数组。解决这个问题的最简单方法是让服务器返回一个没有命名键的数组。您还可以在每次请求后以角度转换响应(更昂贵)。

【讨论】:

  • 这个答案拯救了我的一天,但是为什么,......为什么不能过滤处理命名键?
  • @jvannistelrooy 它根本没有实现,但有补丁待定。你可以在这里表达你对这个功能的支持:github.com/angular/angular.js/pull/6695 或这里github.com/angular/angular.js/issues/6490 过滤器目前被 Angular 开发人员忽略(因为他们正在处理不同的东西)所以越多的人请求这个功能,它就越有可能最终实施。
  • 我不认为这个答案是正确的。可以通过同时应用过滤器的对象的对象进行 ng-repeat。看看这个:stackoverflow.com/questions/41743724/…
【解决方案2】:

正如 Narretz 已经提到的,Angular 过滤器不能将对象的对象作为输入处理。但是您可以编写自己的简单过滤器,将对象的对象转换为对象数组。您可以通过链接使用 array 过滤器后面的角度过滤器。

<ul data-ng-repeat="catalog in catalogs | array | filter:catalog_filter">

你的 array 过滤器可以这么简单:

app.filter('array', function() {
  return function(items) {
    var filtered = [];
    angular.forEach(items, function(item) {
      filtered.push(item);
    });
   return filtered;
  };
});

【讨论】:

  • 当您第 10 次阅读文档时,不知何故不清楚即使使用 $ 也不能使用 Objects。 THX
【解决方案3】:

假设您想使用分销商名称过滤目录,那么以下自定义过滤器可以完成这项工作:

<div data-ng-controller="dashboard_controller">

<h1>
    Catalogs
    <input type="text" data-ng-model="catalog_filter"  placeholder="Filter Distributors">
</h1>

    <div class="catalogs_listing">
        <ul data-ng-repeat="catalog in catalogs | distributorName: catalog_filter:distributors">
            <li> <a href="{{catalog.distributor_id}}/d/products/catalog_view/{{catalog.uid}}">
                <div class="catalog_thumb">
                    <div class="catalog_thumb_image">
                        <span>demo - no image</span>
                    </div>
                </div>
                <div class="catalog_info">
                    <h2>{{distributors[catalog.distributor_id].name}} <span>{{catalog.products_count}}p</span></h2>
                    <p>{{catalog.name}}</p>
                </div>
            </a>

            </li>
        </ul>
    </div>
</div>

app.filter('distributorName', function() {
  return function(items, filterValue, distributors) {
      if (!filterValue){
          return items;
      }  
      var result = {};
        angular.forEach(items, function(value, key) {
            var distributor = distributors[value.distributor_id];
            if (distributor && distributor.name && distributor.name.toLowerCase().indexOf(filterValue.toLowerCase()) > -1){
                result[key] = value;
            }
        });
        return result;
    };
});

JSFiddle 处理本地数据:http://jsfiddle.net/alfrescian/p8zgp/

【讨论】:

    【解决方案4】:

    了解非常有帮助...这是 alfrescian 解决方案的更通用版本,通过子键过滤对象列表。

    app.filter('objFilter', function() {
      return function(items, filter) {
          if (!filter){
              return items;
          }  
          var result = {};
            angular.forEach( filter, function(filterVal, filterKey) {
              angular.forEach(items, function(item, key) {
                  var fieldVal = item[filterKey];
                  if (fieldVal && fieldVal.toLowerCase().indexOf(filterVal.toLowerCase()) > -1){
                      result[key] = item;
                  }
              });
            });
            return result;
        };
    });
    

    然后你可以有多个过滤器框,像这样

    <input ng:model="filter.firstName"/>
    <input ng:model="filter.lastName"/>
    <input ng:model="filter.email"/>    
    

    你的ng-repeat 看起来像这样

    <ul ng:repeat="cust in customers | objFilter: filter">
      <li>
        <a href="mailto:{{cust.email}}">{{cust.firstName}} {{cust.lastName}}</a>
      </li>
    </ul>
    

    【讨论】:

      【解决方案5】:

      您可以使用toArrayFilter 将对象转换为数组,以便常规过滤器使用它。

      在你的情况下,它会是:

      <div ng-repeat="catalog in catalogs | toArray | filter:catalog_filter">
        {{ catalog.$key }} - {{ catalog.someProp }}
        <!-- code -->
      </div>
      

      【讨论】:

        【解决方案6】:

        有什么值得一提的...

        鉴于,这是一个极端案例,但我想我会分享。

        你有一个数据结构;它需要是一个集合,但由于预期的增长、复杂性或其他限制,它需要非常SOLID 的基础知识和自己的方法。所以你决定将这个对象原型化为一个数组

        var OrdersDataModel = function OrdersDataModel(orders) {
            var thus = this;
            var orders = orders || [];
        
            function loadData(data) {
                this.splice.apply(this, [0, this.length].concat(data || orders));
                return this;
            }
            function serialize() {
                var serialized = JSON.stringify(this);
                return serialized;
            }
            function marshalData() {
                var marshalled = JSON.parse(this.serialize());
                return marshalled;
            }
        
            // export precepts
            this.load = loadData;
            this.serialize = serialize;
            this.marshalData = marshalData;
        
            return this;
        };
        OrdersDataModel.prototype = new Array();
        

        这可能适合您的需求并在您的 ng-repeat 中表现良好——直到需要 filter 您的“数组”:

        <element ng-repeat="order in orders | filter:q" />
        

        您的过滤器将失败(可能只是由于类型检查),您可能会浪费一点时间。

        在我的情况下,可以通过修改我的 serialize 方法来轻松解决

        var serialized = JSON.stringify(this);
        

        -- 到--

        var serialized = JSON.stringify(this.slice(0));
        

        不过,实现我的目标的更好方法是使用 Decorator PatternConstructor-Hijacking 来装饰数组:

        代替:

        OrdersDataModel.prototype = new Array();
        ...
        this.orders = new OrdersDataModel();
        this.orders.load(serverData);
        

        -- 使用--

        this.orders = OrdersDataModel.apply([]);
        this.orders.load(serverData);
        

        其中很多可能看起来有点无关紧要,但我希望它(及其包含的模块/控制器)能够快速扩展,因此我尽可能多地使用 SOLID 以保持其密封性。

        希望这可以为您节省一些时间!

        【讨论】:

          【解决方案7】:

          Angular 过滤器无法将对象的对象作为输入处理,但是,要解决您面临的问题,您可以将监视添加到 catalog_filter。如下:

          $scope.$watch('catalog_filter', function (value) {
                  regex = new RegExp($scope.catalog_filter);
                   if (!$scope.catalog_filter) return true;
                   return regex.test(catalog.uid); /* can create multiple conditions based on the requirement*/
              });
          

          执行此操作时,过滤器会作用于输入文本并在文本更改时进行过滤。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-11-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-08-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多