Brahim Djarallah
Brahim Djarallah

Reputation: 138

Using ng-if with directive take to much time [Slowly]

I have a directive tree list view with checks box, (aleardy developed by another developer), i want to display it to the user when he clicks on button, so i used ng-if/ng-show/ng-hide/ng-class with hidden. they takes a lot of time to display the directive (tree list), (more then 20sec)

the directive use ng-if, ng-repeat, ng-show...

When i use: ng-if: 1- page loading is ok 2- display tree list after click button is slowly ng-hide/ng-show/ng-class with hidden: 1- page loading is noy ok (too slowly) 2- display tree list after click button is OK

any advices for this problem ?

the template of my directive is:

template: [
      '<div>',
        '<div>',
          '<span ivh-treeview-toggle="node">',
            '<span class="ivh-treeview-twistie">',
              '<span class="ivh-treeview-twistie-expanded">',
                ivhTreeviewOptions().twistieExpandedTpl,
              '</span>',
              '<span class="ivh-treeview-twistie-collapsed">',
                ivhTreeviewOptions().twistieCollapsedTpl,
              '</span>',
              '<span class="ivh-treeview-twistie-leaf">',
                ivhTreeviewOptions().twistieLeafTpl,
              '</span>',
            '</span>',
          '</span>',
          '<span ng-if="ctrl.useCheckboxes()"',
              'ivh-treeview-checkbox="node">',
          '</span>',
          '<span class="ivh-treeview-node-infos" ng-class="{\'billable\': ctrl.billable(node), \'associatedToUser\': ctrl.associatedToUser(node), \'hasAncestorAssociatedToUser\': ctrl.hasAncestorAssociatedToUser(node), \'nonClickable\': !ctrl.clickable(node)}" ivh-treeview-click>',
            '<span class="ivh-treeview-node-additionalInfo" ng-if="ctrl.showUserGroupUserCount()">',
              '<span ng-if="ctrl.userCount(node)" title="{{\'USERGROUP_USER_COUNT\' | translate}}" class="cursorHelp"><i class="fa fa-users fa-spr"></i>{{ctrl.userCount(node)}}</span>',
            '</span>',
            '<span class="ivh-treeview-node-additionalInfo" ng-if="ctrl.showRoleUserCount()">',
              '<span ng-if="ctrl.userCount(node)" title="{{\'ROLE_USER_COUNT\' | translate}}" class="cursorHelp"><i class="fa fa-users fa-spr"></i>{{ctrl.userCount(node)}}</span>',
            '</span>',
            '<span class="ivh-treeview-node-label">',
              '<span title="{{\'ROLE_ASSOCIATED_TO_USER\' | translate}}" class="cursorHelp labelIcon" ng-if="ctrl.associatedToUser(node)"><i class="fa fa-tag fa-spr"></i></span>',
              '<span title="{{\'USERGROUP_BILLABLE\' | translate}}" class="cursorHelp labelIcon" ng-if="ctrl.billable(node)"><i class="fa fa-credit-card fa-spr"></i></span>',
              '<span ng-if="ctrl.translate()">{{ctrl.label(node) | translate}}</span>',
              '<span ng-if="!ctrl.translate()">{{ctrl.label(node)}}</span>',
            '</span>',
            '<span class="ivh-treeview-node-description" ng-if="ctrl.showDescription()">',
              '{{ctrl.description(node)}}',
            '</span>',
          '</span>',
        '</div>',
        '<ul ng-if="getChildren().length" class="ivh-treeview">',
          '<li ng-repeat="child in getChildren()"',
              'ng-hide="ctrl.hasFilter() && !ctrl.isVisible(child)"',
              'ng-class="{\'ivh-treeview-node-collapsed\': !ctrl.isExpanded(child) && !ctrl.isLeaf(child)}"',
              'ivh-treeview-node="child"',
              'ivh-treeview-depth="childDepth">',
          '</li>',
        '</ul>',
      '</div>'
    ].join('\n')
  };
}])

Upvotes: 0

Views: 201

Answers (1)

hoeni
hoeni

Reputation: 3280

Since there's a lot of context missing this might or might not help you. Two things come to my mind:

1. Use track by expression

You should always use a track by expression in ng-for-loops with lots of data, so angular knows which elements are which and can reuse DOM-elements on changes to save time:

<li ng-repeat="child in getChildren() track by child.id
  ...

In this case I assume your children have a unique "id" property, Choose a unique property of yours.

2. Don't use a dynamic method to generate children lists

Every time AngularJS runs a change detection cycle, it will have to call your function getChildren() over and over again. In almost every case this is more expensive than generating a children list once on initialization and write it to a scope variable that can be checked by the change detection much cheaper then.

Upvotes: 0

Related Questions