timh
timh

Reputation: 1590

A more efficient way to highlight a row in ng-repeat? ... the angular way

I've illustrated this idea here: http://plnkr.co/edit/lPHWba9e4WqXmQLMmplv?p=info

Imagine a list of items built with ng-repeat...

      <tr ng-repeat="item in items">
           <td id="{{item.id}}">item.id</td>
      </tr>

I would like a way for an outside module to highlight one of the rows. One way is to use jquery:

     function hilite(id){
        $('#'+id).css('background-color', '#f33');  
     }

What is the angular way? ... here's one option:

      <tr ng-repeat="item in items">
           <td css="{{hiliteID==item.id && 'background:#f33;'}}" id="{{item.id}}">item.id</td>
      </tr>

But wouldnt this way be much slower? (Imagine this in an app that is already burdened by angular needing to $watch tens of thousands of items in a $scope... where little things matter)

Check my plunkr... can you think of a better way to do this... that is not jquery? http://plnkr.co/edit/lPHWba9e4WqXmQLMmplv?p=info

Upvotes: 0

Views: 237

Answers (1)

Nikos Paraskevopoulos
Nikos Paraskevopoulos

Reputation: 40308

I will probably be accused of heresy but I wouldn't mind using jQuery (or similar) if there is good reason for it. Some thoughts:

  1. If highlighting is just a transient effect (in the sense of $.effect("highlight") - ref - THIS IS NOT THE CASE HERE), I believe jQuery would be a good option for optimization.
  2. If you really mind the watches (you should in general, when models start getting bigger), why not implementing this functionality in a directive applied to the root of the list. Some pseudo-code to explain:

    <tbody highlighter="some.expression.here">
        <tr ng-repeat="item in items">
            <td id="{{item.id}}">item.id</td>
        </tr>
    </tbody>
    

    So, the highlighter directive knows somehow to highlight a row by applying a single watch, e.g (again very rough almost-pseudo-code):

    // in the link(scope,elem) function:
    scope.$watch("highlightedRowId", function(newval, oldval) {
        elem.find("#" + oldval).removeClass("highlighted");
        elem.find("#" + newval).addClass("highlighted");
    });
    
  3. (as haki comments) Does the model really need to get this big? Are there any ways to avoid it? Is the trade-off "Use jQuery and less watches" vs. "Clean code and more watches" worth it?

These are just some very rough thoughts on an interesting and open ended question... Actually I started writing a comment, but it became too long soon. Have fun anyway!

Upvotes: 1

Related Questions