Frage

I have created a directive for displaying large amounts of data in a tree structure. When an element is collapsed, its content is hidden using the ng-show command.

Here is a heavily simplified version on plunker.

The directive is called collapsible-test, and is used as so:

<div collapsible-test>
    <p>Here is some content....</p>
    <div collapsible-test>
        <p>Here is some more content....</p>
        <div collapsible-test>
            <p>Here is even more content....</p>
        </div>
    </div>
</div>

The part of the directive template that controls the collapsing looks like this:

<div ng-show="!collapsed" class="panel-body">
    <div ng-transclude></div>
</div>

This all works fine, however I will need to use it for hundreds of nested elements using ng-repeat. This causes the page to take 10-15 seconds to load, and then there are also great delays when expanding and collapsing the elements.

I tried to alleviate this by replacing the ng-show directive with ng-switch. (I'll use ng-if when I update angular at a later date.) This approach does not work, because using the transclude service on DOM elements that are not yet present generates an error.

<div ng-switch="collapsed">
    <div ng-switch-when="false" class="panel-body">
        <div ng-transclude></div>
    </div>
</div>

I thought I might have to recompile every time I change the 'collapse' state, but I can't understand how to make it work.

Or, perhaps there is a better way to solve my problem that I haven't thought of yet.

EDIT:

OverZealous answered my question perfectly, thanks! This is just an update for those who try to dosomething similar. This method will only work outside of an ng-repeat loop. It appears that ng-if converts the DOM code into a comment when it fails the test. Therefore, ng-repeat will do nothing but repeat the comment (or something like that). So ng-if and ng-switch are still not foolproof, but they are fine you don't require ng-repeat.

War es hilfreich?

Lösung

If you can upgrade to Angular.js 1.1.5 (a prerelease) or 1.2.0-rc2 (a release candidate), you can use ng-if to make this work.

Example Plunker.

Template:

<div class="panel-body">
    <div ng-if="!collapsed" ng-transclude></div>
</div>

What I did is changed the ng-show to ng-if, and moved it directly onto the ng-transclude element. This appears to work, and if you look at the DOM in your developer tools, you can see that all descendent nodes are removed when the parent is collapsed.

Note that all child elements are rebuilt when a parent is expanded, so unless you save the collapsed state somewhere, the child nodes are re-created in the collapsed state. This may be confusing for your users.


If you can't upgrade to the latest release

You can use the ngIf provided by Angular UI, which should work exactly the same:

https://github.com/angular/angular.js/blob/master/src/ng/directive/ngIf.js

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top