AngularJS smart-table weird behavior with nested objects and st-search

I am trying to implement the Smart Table module in my AngularJS application. I would prefer this over some others mainly because others seemed to need as much template code in my controller, and I like to keep my controllers as dry as possible. But I'm open to other modules that can do the same thing without a template.

It works great when working with a linear array, but if some of these objects have nested objects, filtering and sorting have strange behavior.

This will require some explanation, so bear with me.

First of all, here is my array of nested objects (shortened for readability):

$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 is 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 everything works fine if my array has no nested objects. But with nested objects (for example, st-search="new.price" I get the following problems (see screenshot):

  • Sometimes, when I enter text in the search field of a "nested object", all other fields that also have nested objects inherit the same value (but filtering still works fine). It doesn’t always do it, just sometimes ...
  • Boolean values ​​for nested objects are not calculated correctly. True display all the entries, but False will only show the entry whose value is False .

Screenshot of Result

Has anyone else figured out how to handle nested objects and the smart table module?

+5
source share
2 answers

As laurent said you need to use your own filter

Use st-set-filter to set the filter

 <table st-table="displayedProducts" st-safe-src="products" st-set-filter="customFilter" class="table table-striped table-bordered table-hover"> 

Define a custom filter in your module

 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; }; }]) 
+1
source

You need to use a copy of your collection, so instead of directly assigning $scope.displayedProducts = $scope.products; you must do $scope.displayedProducts= $scope.displayedProducts.concat($scope.products);

0
source

Source: https://habr.com/ru/post/1204942/


All Articles