0

I have created a custom directive to out put a fairly simple tabular data. This is my current code:

app.directive('searchResult', function () {
    return {
        restrict: 'E',
        scope: { content: '=' },
        link: function (scope, element, attrs) {
            var html = '<table class="table table-bordered">';
            angular.forEach(scope.rows, function (row, index) {
            if (row.names.length > 1) { 
               var names = row.names;
                html += '<tr>';
                html += '<td rowspan='+row.names.length+'>'+row.num +'</td>';
                html += '<td>'+names[0] + '</td>';
                html += '</tr>'

                for (var i = 1; i < names.length; i++) {
                   html += '<tr>';
                   html += '<td>'+names[i] +'</td>';
                   html += '</tr>';
                }
           } else {
                html += '<tr>';
                html += '<td>'+row.num +'</td>';
                html += '<td>'+row.names[0] + '</td>';
                html += '</tr>';
        }
        })
        html += '</table>';
        element.replaceWith(html)
        }
    }
});

The problem with this code is the binding. If a user searches a new item, the directive will create a new table above the previously displayed result instead of replacing the old result.

I am trying to use templateUrl and have a template that has {{content}} inside and the binding works. The old search result is replaced by the new one.

Is there a way to perform this table code creation inside a template?

2 Answers 2

1

Use $compile service after you are done with your html.

$compile

Instead of:

element.replaceWith(html)

Try:

html = $compile(html);

It should keep all Angular.js binding. However it is not a good practice, as you are forcing an extra scope refresh.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks! May I know what the best practice would be?
Create external template, use ng-repeat. Dont concate strings inside your javascript. Dont use forEach use for loop and your brain. jsperf.com/for-vs-foreach/37
Got it. I didn't know you can do that with just ng-repeat. Thanks!
0

I solved the my case using templates by using this code:

<table class="table table-bordered">
    <tbody>            
        <tr ng-repeat-start='myEntry in content'>
            <td rowspan="{{myEntry.names.length}}">{{myEntry.num}}</td>
            <td>{{myEntry.names[0]}}</td>
        </tr>
        <tr ng-repeat-end ng-repeat='name in myEntry.names' ng-if="$index > 0">
            <td>{{name}}{{myEntry.names}}</td>
        </tr>
    </tbody>
</table>

Some of the codes are based from the links found in SO:

Thanks it Michał Lach for pointing out of a more elegant way of doing this.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.