-3

I have a html table whose table data are connected to an array having bunch of objects (ex:{key:abc,value:100},{key:ac,value:200}). I am using angularjs and with the aid of ng-repeat directive I populate my table data with this array. Also I have one more functionality in the application, there is a dropdown and when a user selects an item from this drop down it gets pushed to my array of objects and since array is binded to my table so table gets dynamically updated. Similar is the procedure for deletion. Now, my question is user only add or removes a single item at a time and due to change in model whole table is re-rendered from scratch though I need addition/deletion of just one row. I mean I need diff of past state and current state to be appended but actually I am re-rendering whole table which is computationally very expensive. Is there a way I can avoid it? As I said I am using Angular. I havent used React from facebook but I read somewhere it works on a similar concepts of diffs.

Here is some code: Table in HTML file connected to selectedProducts array.

<table class="table table-condensed table-bordered table-striped" ng-show="selectedProducts.length>0">

Dropdown present in HTML file which adds selected item to selectedProducts array.

<select id='select_product' class='form-control' ng-model="selected_product" ng-options="product.key for product in products" ng-change="selectedProducts.push(selected_product)"></select>

This is how table rows are genereated:

<tr ng-repeat="selected_product in selectedProducts track by $index">
     <td>{{selected_product.key}}</td>
     <td>{{selected_product.value}}</td>
     <td><a href ng-click="selectedProducts.splice($index, 1)">X</a></td>
</tr>

Array defined in the js file:

$scope.selectedProducts = [];
JackSparrow
  • 187
  • 1
  • 2
  • 15

1 Answers1

0

$index is going to change for many rows when you remove a product, therefore at least those will be re-rendered. If selected_product.key is always going to be unique, then you should track by that.

Also, you should avoid using $index for splicing, per the accepted answer here: How do I delete an item or object from an array using ng-click?

Instead do:

ng-click="remove(selected_product)"

and

$scope.remove = function(item) { 
  var index = $scope.bdays.indexOf(item)
  $scope.bdays.splice(index, 1);     
}
Community
  • 1
  • 1
David Williams
  • 229
  • 2
  • 10
  • Yup that is a good advice ....but I wonder this will prevent re-rendering of table at the DOM level...I want to know how angular modifies DOM when corresponding underlying model changes ....does it try to do the minimal needed change to modify the DOM or does it completely remove the older element and replaces it with a new one by completely re-rendering it from scratch ? – JackSparrow Jan 05 '15 at 15:30
  • I was looking at this a few months ago (with help from this blog: http://www.bennadel.com/blog/2556-using-track-by-with-ngrepeat-in-angularjs-1-2.htm) where I update a table model heavily and monitor performance. I was fairly sure that once you add a track by, it will re-render only the rows (and cells) that it needs to. It certainly heavily improved the performance of my table. If you provide a jsFiddle or something I can check your specific scenario. – David Williams Jan 07 '15 at 01:38