json angularjs 过滤器(不工作)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17672614/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
angularjs filter (not working)
提问by Nir Gavish
The following HTML, Javascript and JSON render correctly, but the filter does not work at all. What are we doing wrong?
以下 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>
The Javascript:
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;
});
});
And these 2 JSONs:
而这 2 个 JSON:
api/distributors/my:
API/分销商/我的:
{
"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/dashboard/catalogs
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"
}
}
回答by Narretz
Angular filters cannot handle an object of objects as input. ng-repeat can render them, but filters expect an array of objects. The easiest way to fix this is to let the server return an array without named keys. You could also transform the response in angular after each request (more expensive).
角度过滤器无法将对象的对象作为输入处理。ng-repeat 可以渲染它们,但过滤器需要一个对象数组。解决这个问题的最简单方法是让服务器返回一个没有命名键的数组。您还可以在每次请求后以角度转换响应(更昂贵)。
回答by Holger
As Narretz already mentioned, Angular filters cannot handle an object of objects as input. But you can write your own simple filter converting the object of objects into an array of objects. You can use the angular filters behind your arrayfilter by chaining.
正如 Narretz 已经提到的,Angular 过滤器无法将对象的对象作为输入处理。但是您可以编写自己的简单过滤器,将对象的对象转换为对象数组。您可以通过链接使用阵列过滤器后面的角度过滤器。
<ul data-ng-repeat="catalog in catalogs | array | filter:catalog_filter">
Your arrayfilter could be as simple as this:
您的数组过滤器可以像这样简单:
app.filter('array', function() {
return function(items) {
var filtered = [];
angular.forEach(items, function(item) {
filtered.push(item);
});
return filtered;
};
});
回答by alfrescian
Assuming that you'd like to filter in catalogs using distributor name then the following custom filter does the job:
假设您想使用经销商名称在目录中进行过滤,那么以下自定义过滤器可以完成这项工作:
<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 with local data: http://jsfiddle.net/alfrescian/p8zgp/
带有本地数据的 JSFiddle:http: //jsfiddle.net/alfrescian/p8zgp/
回答by stukennedy
Very helpful to know ... here's a more generic version of alfrescian's solution, to filter a list of objects by a sub-key.
知道非常有帮助......这是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;
};
});
You can then have multiple filter boxes, like this
然后你可以有多个过滤器框,像这样
<input ng:model="filter.firstName"/>
<input ng:model="filter.lastName"/>
<input ng:model="filter.email"/>
And your ng-repeatwould look like this
你ng-repeat会看起来像这样
<ul ng:repeat="cust in customers | objFilter: filter">
<li>
<a href="mailto:{{cust.email}}">{{cust.firstName}} {{cust.lastName}}</a>
</li>
</ul>
回答by Bruno Peres
You can use the toArrayFilterthat converts the object to an array so it can be used by regular filters.
您可以使用toArrayFilter将对象转换为数组,以便常规过滤器可以使用它。
In your case it would be as:
在您的情况下,它将是:
<div ng-repeat="catalog in catalogs | toArray | filter:catalog_filter">
{{ catalog.$key }} - {{ catalog.someProp }}
<!-- code -->
</div>
回答by Cody
What Is Worth Mentioning...
值得一提的是...
Given, this is rather a corner case, but I thought I'd share.
鉴于,这是一个角落案例,但我想我会分享。
You've a data-structure; it needs to be a collection, but it requires very SOLIDfundamentals and its own methods due to expected growth, complexity, or other constraints. So you decide to prototype this object as an array.
你有一个数据结构;它需要是一个集合,但由于预期的增长、复杂性或其他限制,它需要非常可靠的基础知识和自己的方法。因此,您决定将此对象原型化为数组。
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();
This may suit your needs and perform well in your ng-repeat-- until comes the need to filteryour "array":
这可能适合您的需求并在您的ng-repeat- 中表现良好- 直到需要filter您的“阵列”:
<element ng-repeat="order in orders | filter:q" />
Your filter will fail (probably simply due to type-checks), and you'll wast a little time perhaps.
您的过滤器将失败(可能仅仅是由于类型检查),而且您可能会浪费一点时间。
In my case, it can be easily remedied by modding my serializemethod from
在我的情况下,可以通过修改我的serialize方法来轻松解决
var serialized = JSON.stringify(this);
-- to --
- 到 -
var serialized = JSON.stringify(this.slice(0));
Though, a much better way to accomplish my goal would be to decorate an array using either the Decorator Patternor Constructor-HiHymaning:
不过,实现我的目标的更好方法是使用装饰器模式或构造函数劫持来装饰数组:
Instead of:
代替:
OrdersDataModel.prototype = new Array();
...
this.orders = new OrdersDataModel();
this.orders.load(serverData);
-- use --
- 用 -
this.orders = OrdersDataModel.apply([]);
this.orders.load(serverData);
A lot of this may seem a little extraneous, but I expect this (and its encompassing module/controller) to expand quickly, so I've stuck as much to SOLID as possible to keep it air-tight.
很多这可能看起来有点无关紧要,但我希望它(及其包含的模块/控制器)能够快速扩展,所以我尽可能多地使用 SOLID 以保持气密性。
Hope this saves you some time!
希望这可以为您节省一些时间!
回答by CodeWarrior
Angular filters cannot handle an object of objects as input, however, to resolve the issue you are facing, you can add a watch to the catalog_filter. As follows:
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*/
});
Doing this the filter acts on the input text and filters when the text changes.
这样做时,过滤器会作用于输入文本并在文本更改时进行过滤。

