问题
I'm trying to implement the Smart Table module in my AngularJS app. I'd prefer this over some others mainly because the others seemed require a lot of boilerplate code in my controller and I like to keep my controllers as DRY as possible. But I'm open to other modules that can accomplish the same thing without boilerplate.
It works great when dealing with a straight-up array of objects, but if some of those objects have nested objects, the filtering and sorting has strange behavior.
This will take some explaining so bear with me.
First of all, here is my array of nested objects (shortened for readability here):
$scope.products = [
{
'display': 'Live',
'name': 'LC1D09',
'category': 'Motor Control',
'subcategory': 'Contactor',
'manufacturer': 'Telemecanique',
'specs': {
'phase': 3,
'poles': 3
},
'new': {
'price': 158.95
},
'refurbished': {
'price': 145
},
'onlineStores': {
'amazon': true,
'ebay': false
},
'isCool': true
},
{
'display': 'Pending',
'name': 'FA32020',
'category': 'Circuit Breaker',
'subcategory': 'Molded Case',
'manufacturer': 'Square D',
'specs': {
'phase': 1,
'poles': 2
},
'new': {
'price': 217.79
},
'refurbished': {
'price': 192.82
},
'onlineStores': {
'amazon': true,
'ebay': true
},
'isCool': false
}
];
$scope.displayedProducts = $scope.products;
Here's my HTML:
<table st-table="displayedProducts" st-safe-src="products" class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th st-sort="name">Name</th>
<th st-sort="category">Category</th>
<th>Subcategory</th>
<th>Manufacturer</th>
<th>New Price</th>
<th>Refurb. Price</th>
<th>Display</th>
<th>Specs</th>
<th>Cool</th>
</tr>
<tr>
<th><input st-search="'name'" placeholder="" class="input-sm form-control" type="search"/></th>
<th><input st-search="'category'" placeholder="" class="input-sm form-control" type="search"/></th>
<th><input st-search="'subcategory'" placeholder="" class="input-sm form-control" type="search"/></th>
<th><input st-search="'manufacturer'" placeholder="" class="input-sm form-control" type="search"/></th>
<th><input st-search="new.price" placeholder="" class="input-sm form-control" type="search"/></th>
<th><input st-search="refurbished.price" placeholder="" class="input-sm form-control" type="search"/></th>
<th><input st-search="'display'" placeholder="" class="input-sm form-control" type="search"/></th>
<th><input st-search="'specs'" placeholder="" class="input-sm form-control" type="search"/></th>
<th>
<select st-search="onlineStores.ebay" class="form-control">
<option value=""></option>
<option value="true">Yes</option>
<option value="false">No</option>
</select>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="product in displayedProducts">
<td>{{product.name}}</td>
<td>{{product.category}}</td>
<td>{{product.subcategory}}</td>
<td>{{product.manufacturer}}</td>
<td>${{product.new.price | number : 0}}</td>
<td>${{product.refurbished.price | number : 0}}</td>
<td>{{product.display}}</td>
<td>{{product.specs}}</td>
<td>{{product.onlineStores.ebay}}</td>
</tr>
</tbody>
</table>
So this all works fine if my array doesn't have nested objects. But with the nested objects (eg st-search="new.price"
I get the following issues (see the screenshot):
- Sometimes when I enter text in a "nested object" search field, all other fields that also have nested objects inherit the same value (but the filtering still works fine). This doesn't always do this, just sometimes...
- Boolean values on nested objects don't compute correctly.
True
will show all records, butFalse
will show only the record whose value isFalse
.
Anybody else figured out how to deal with nested objects and the smart-table module?
回答1:
As laurent said, you need to use a custom filter
Use st-set-filter to set your filter
<table st-table="displayedProducts" st-safe-src="products" st-set-filter="customFilter" class="table table-striped table-bordered table-hover">
In your module, define a custom filter
angular.module('myModule').filter('customFilter', ['$parse', function($parse) {
return function(items, filters) {
var itemsLeft = items.slice();
Object.keys(filters).forEach(function(model) {
var value = filters[model],
getter = $parse(model);
itemsLeft = itemsLeft.filter(function(item) {
return getter(item) === value;
});
});
return itemsLeft;
};
}])
回答2:
You need to use a copy of your collection, so instead of doing the direct assignment $scope.displayedProducts = $scope.products;
you should do $scope.displayedProducts= $scope.displayedProducts.concat($scope.products);
来源:https://stackoverflow.com/questions/26431774/angularjs-smart-table-strange-behavior-with-nested-objects-and-st-search