2013-09-26 41 views
1

我建立一个使用Bootstrap Collapse组件以使面板的序列中的应用,所有这些最初将处于收缩状态。如何使用AngularJS懒加载内容的可折叠面板

由于页面可能包含许多这样的面板,它们可以各自含有大量的内容,似乎是适当的填充点播这些面板,当用户展开任何面板执行AJAX调用。

使用AngularJS呈现页面的动态内容(包括面板的标记),并且我认为可以将Angular配置为绑定到面板元素上的事件,导致其内容被延迟加载时他们扩大。

不幸的是,看着AngularJS文档和可用的教程后,我看不出如何最好地解决这一点。任何人都可以对此有所了解吗?

由于提前,

+0

只需在面板内部使用'

',并在打开面板时定义/设置'panelTemplate' var。这将仅在面板第一次打开时执行XHR请求并获取面板视图。 – Stewie

+0

谢谢Stewie。这看起来很有前途,但我不清楚如何在面板打开时触发panelTemplate的define/set。如果您想用代码示例发布答案,我会尝试它并(可能)接受它。谢谢。 –

回答

2

@Tim库尔特,我创建的东西以下@Stewie的想法。

它绝对可以改善,但我想这是一个很好的起点。

我创建了一个小的指令手风琴的面板的单击事件绑定。点击事件时,我通过panel-template=属性传递面板模板,并更新在面板内部使用的main-template

它使参考对包含各面板的内容2个的HTML文件(panel1.html和panel2.html)。 我建议创建一个服务来通过AJAX获取这些文件 - 就像你想要的那样。 在下面的代码中,我为此创建了一个名为dataService的服务,并且您应该将其绑定到click事件 - 因此当用户单击它时,会按需加载文件。

注意的mainTemplate是一种常见的面板全部手风琴,所以当它改变了所有的手风琴将具有相同的内容,但我假设你想在时间显示只有一个面板,对吧?!

反正我之前说的逻辑可以提高解决这些小“陷阱”,但我相信的核心功能是在那里开始。 :)

<!doctype html> 
<html ng-app="myApp"> 
    <head> 
    <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> 
    <script src="http://code.jquery.com/jquery-migrate-1.2.1.min.js"></script> 
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js"></script> 
    <script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script> 

    <link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet"> 

    <script> 

    var myApp = angular.module('myApp', []); 


    myApp.controller('AccordionDemoCtrl', ['$scope', 'dataService', function ($scope, dataService) { 
     $scope.oneAtATime = true; 

     $scope.mainTemplate = ''; 

     $scope.groups = [ 
      { 
      id: "001", 
      title: "Dynamic Group Header - 1", 
      content: "Dynamic Group Body - 1", 
      template: "panel1.html" 
      }, 
      { 
      id: "002", 
      title: "Dynamic Group Header - 2", 
      content: "Dynamic Group Body - 2", 
      template: "panel2.html" 

      } 
     ]; 

    }]); 

    myApp.factory('dataService', [ '$http', function($http){ 
     return { 
      getData: function() { 
      return // you AJAX content data here; 
      } 
     } 
    }]); 

    myApp.directive('accordionToggle', [function() { 
     return { 
     restrict: 'C', 
     scope: { 
     mainTemplate: '=', 
     panelTemplate: '@' 
     }, 
     link: function (scope, element, iAttrs) { 

     element.bind('click', function(e){ 

      scope.mainTemplate = scope.panelTemplate; 

      scope.$apply(); 

     }); 
     } 
    }; 
    }]); 


    </script> 

    </head> 
    <body ng-controller="AccordionDemoCtrl"> 

    <div class="accordion" id="accordionParent"> 
    <div class="accordion-group" ng-repeat="group in groups" > 
    <div class="accordion-heading"> 
     <a class="accordion-toggle" main-template="$parent.mainTemplate" panel-template="{{ group.template }}" data-toggle="collapse" data-parent="#accordionParent" href="#collapse{{ $parent.group.id }}"> 
     Collapsible Group Item {{ $parent.group.id }} 
     </a> 
    </div> 
    <div id="collapse{{ group.id }}" class="accordion-body collapse"> 
     <div class="accordion-inner"> 
     <div class="include-example" ng-include="mainTemplate"></div> 
     </div> 
    </div> 
    </div> 
</div> 

    </body> 
    </html> 
+1

这是一个很好的解决方案。感谢您花时间为我创建它。 –

+2

这是一个很好的解决方案,甚至可以用于基础手风琴。感谢分享这个。对于那些对角度基础解决方案感兴趣的人,我将分享这个夯脚:http://plnkr.co/edit/KkZlqs3UDdYE0805DTm9?p=preview – ka8725

2

这是古老的,但问题可能会不时出现。现在我觉得这是不污染你的控制器是最合适的解决方案:(myDirective其创建后加载通过AJAX的内容)

<accordion> 
    <accordion-group 
    heading="" 
    ng-repeat="foo in bar" 
    ng-init="status = {load: false}" 
    ng-click="status.load = true"> 

    <myDirective ng-if="status.load"></myDirective> 
    </accordion-group> 
</accordion> 

通过ng-repeat创建的每个元素都有自己的$范围,所以点击AB手风琴组将导致只加载相应的指令。

编辑: 根据延迟和数据的大小,这是可以延迟加载,你可以考虑使用ng-mouseover代替ng-click。这种方式在用户打开手风琴之前大约100ms开始,这可以减少UI的“迟钝”。显然,偶尔加载从未实际点击的组内容的缺点。