1

我正在构建一个应用程序,它使用Bootstrap Collapse组件来呈现一系列面板,所有这些面板最初都将处于折叠状态。

由于页面可能包含许多这样的面板,并且每个面板都可能包含大量内容,因此通过在用户展开任何面板时执行 AJAX 调用来按需填充这些面板似乎是合适的。

页面的动态内容(包括面板的标记)是使用 AngularJS 呈现的,我假设可以将 Angular 配置为绑定到面板元素上的事件,这会导致它们的内容在展开时被延迟加载。

不幸的是,在查看了 AngularJS 文档和可用教程之后,我看不出如何最好地解决这个问题。任何人都可以照亮它吗?

提前致谢,

蒂姆

4

2 回答 2

3

这已经很老了,但问题可能仍然会不时出现。我现在发现这是最合适的解决方案,不会污染您的控制器:(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都有自己的 $scope,因此单击 ab 手风琴组将导致仅加载相应的指令。

编辑:根据延迟和要延迟加载的数据的大小,您可以考虑使用ng-mouseover而不是ng-click. 这种方式在用户打开手风琴之前大约 100 毫秒开始加载,这可以减少 UI 的“迟缓”。显然,偶尔加载从未实际点击过的组的内容是不利的。

于 2015-09-03T15:01:49.710 回答
2

@Tim Coulter,我按照@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>
于 2013-09-27T08:24:23.027 回答