2013-09-26 72 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的「遲鈍」。顯然,偶爾加載從未實際點擊的組內容的缺點。