Angular ng-if和ng-show组合

par*_*ent 13 angularjs angularjs-directive

想象一下可能在网页上呈现的一些繁重的内容,例如图表.Angular提供2个选项来切换所述内容的可见性.

ng-show将呈现内容而不管表达式如何,并在事后简单地"隐藏"它.这并不理想,因为用户可能永远不会在会话期间"打开"内容,因此渲染它是一种浪费.

ng-if在这方面更好.如果表达式为false,使用它代替ng-show将防止重型内容首先呈现.然而,它的优势也是它的弱点,因为如果用户隐藏图表然后再次显示它,则每次都从头开始呈现内容.

我怎样才能制定出兼顾两全其美的指令?这意味着它像ng-if一样,直到第一次呈现内容,然后切换到像ng-show一样的工作,以防止每次重新呈现它.

New*_*Dev 20

关于Denis答案的+1,但为了完整起见,甚至可以通过在视图中保持逻辑而不"污染"控制器来进一步简化:

<button ng-click="show = !show">toggle</button>
<div ng-if="once = once || show" ng-show="show">Heavy content</div>
Run Code Online (Sandbox Code Playgroud)

plunker

编辑:上面的版本可以通过一次性绑定进一步改进(和简化),以减少不必要的$ watch once- 这只适用于Angular 1.3+:

<div ng-if="::show || undefined" ng-show="show">Heavy content</div>
Run Code Online (Sandbox Code Playgroud)

undefined需要,以确保观看值不"稳定"成为前true.一旦稳定,它也会失去$ watch,所以它不会受到任何进一步改变的影响show.


Den*_*nov 9

您可以通过使用ngIfngShow一起使其工作,其中每个控制器由不同的变量控制.ngIf将被设置为true一次并且永远不会false再次设置,同时ngShow将切换为用户想要的内容.

看看这个小提琴.


tka*_*rls 5

@ new-dev的回答启发了我自己的组合想法,使用切换按钮快速获得一个非常重的组件.

我最初的问题是我的页面包含~20个组件,每个组件需要大约1秒才能加载.每个人都被一个按钮切换.

如果使用普通ng - 如果我将获得即时页面加载和切换按下后1秒延迟.

如果使用普通的ng-show我会得到即时切换按钮但是20秒的页面加载延迟...

所以,现在我也将它们与ng-mouseenter控制结合起来.像这样.

<div ng-mouseenter="create=true">
    <button ng-click="showAll = !showAll"></button>
    <!--lightweight content-->
    <div ng-show="showAll">
        <div ng-if="create">
            <!--Heavy content-->
        </div>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

这给了我在chrome和IE中的出色表现.用户在进入组件后实际单击按钮所花费的时间用于DOM创建.然后DOM节点快速显示一次(如果)点击到达.

我也从未将ng-if表达式再次设置为false.如果用户保持切换该部分,则保持DOM缓存.

更新:我在同一个div上没有ng-if和ng-show的原因是在IE中它引起了闪烁.当mouseenter事件到达时,它将显示内容然后隐藏它.在chrome中可以将它放在同一个div上.