Skip to content

Commit

Permalink
Feat: support lazy compilation for expansionPanelExpanded's content
Browse files Browse the repository at this point in the history
Close issue B-3PO#52
  • Loading branch information
chenlijun99 committed Dec 28, 2017
1 parent 876127e commit 3a05859
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 61 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ $scope.$on("mdExpansionPanelExpanding", function($event, componentId) {

```
<md-expansion-panel-expanded
[height=""]>
[height=""] [lazy-render=""]>
...
</md-expansion-panel-expanded>
```xpansion-panel>
Expand All @@ -351,6 +351,7 @@ $scope.$on("mdExpansionPanelExpanding", function($event, componentId) {
| Param | Type | Details |
| :--: | :--: | :--: |
| height | number= | <p>add this attribute set the max height of the expanded content. The container will be set to scroll</p> |
| lazy-render | boolean= | <p>if this attribute is present the content of mdExpansionPanelExpanded will be compiled when the mdExpansionPanel expands</p> |



Expand Down
67 changes: 67 additions & 0 deletions app/pages/home/home.html
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,70 @@ <h4>Content</h4>
</md-expansion-panel-expanded>

</md-expansion-panel>

<div style="padding-top: 12px; padding-bottom: 36px;">
<md-divider></md-divider>
</div>

<h2>Lazy render content</h2>
<p>
When there is a long list of expansion panels with heavy content in the expanded area,
it's could take a lot to render all the DOM elements.
In that case use the <code>lazy-render</code> option!
</p>

<md-expansion-panel>

<md-expansion-panel-collapsed>
<div class="md-title">No Sticky</div>
<div class="md-summary">header and footer sticky disabled</div>
</md-expansion-panel-collapsed>

<md-expansion-panel-expanded lazy-render>

<md-expansion-panel-header md-no-sticky>
<div class="md-title">No Sticky</div>
<div class="md-summary">header and footer sticky disabled</div>
</md-expansion-panel-header>

<md-expansion-panel-content>
<h4>Content</h4>
<p>Put content in here</p>

<h4>Content</h4>
<p>Put content in here</p>

<h4>Content</h4>
<p>Put content in here</p>

<h4>Content</h4>
<p>Put content in here</p>

<h4>Content</h4>
<p>Put content in here</p>

<h4>Content</h4>
<p>Put content in here</p>

<h4>Content</h4>
<p>Put content in here</p>

<h4>Content</h4>
<p>Put content in here</p>

<h4>Content</h4>
<p>Put content in here</p>
</md-expansion-panel-content>

<md-expansion-panel-footer md-no-sticky>
<div flex></div>
<md-button class="md-warn" ng-click="$panel.collapse()">Collapse</md-button>
</md-expansion-panel-footer>

</md-expansion-panel-expanded>

</md-expansion-panel>

<div style="padding-top: 12px; padding-bottom: 36px;">
<md-divider></md-divider>
</div>
13 changes: 10 additions & 3 deletions src/js/expansionPanel.directive.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function expansionPanelDirective() {
require: ['mdExpansionPanel', '?^^mdExpansionPanelGroup'],
scope: true,
compile: compile,
controller: ['$scope', '$element', '$attrs', '$window', '$$rAF', '$mdConstant', '$mdUtil', '$mdComponentRegistry', '$timeout', '$q', '$animate', '$parse', controller]
controller: ['$scope', '$element', '$attrs', '$window', '$$rAF', '$mdConstant', '$mdUtil', '$mdComponentRegistry', '$timeout', '$q', '$animate', '$parse', '$compile', controller]
};
return directive;

Expand Down Expand Up @@ -55,7 +55,7 @@ function expansionPanelDirective() {



function controller($scope, $element, $attrs, $window, $$rAF, $mdConstant, $mdUtil, $mdComponentRegistry, $timeout, $q, $animate, $parse) {
function controller($scope, $element, $attrs, $window, $$rAF, $mdConstant, $mdUtil, $mdComponentRegistry, $timeout, $q, $animate, $parse, $compile) {
/* jshint validthis: true */
var vm = this;

Expand Down Expand Up @@ -219,7 +219,7 @@ function expansionPanelDirective() {
options = options || {};

var deferred = $q.defer();
$scope.$emit("mdExpansionPanelExpanding", vm.componentId);
$scope.$emit("mdExpansionPanelExpanding", vm.componentId);

if (vm.epxansionPanelGroupCtrl) {
vm.epxansionPanelGroupCtrl.expandPanel(vm.componentId);
Expand All @@ -235,6 +235,13 @@ function expansionPanelDirective() {

initEvents();
collapsedCtrl.hide(options);

if (expandedCtrl.innerTemplate) {
expandedCtrl.$element.append(expandedCtrl.innerTemplate);
$compile(expandedCtrl.$element.children())($scope);
// set to null to that it gets compile only once
expandedCtrl.innerTemplate = null;
}
expandedCtrl.show(options);

if (headerCtrl) { headerCtrl.show(options); }
Expand Down
130 changes: 73 additions & 57 deletions src/js/expansionPanelExpanded.directive.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,77 +18,93 @@ angular
**/
expansionPanelExpandedDirective.$inject = ['$animateCss', '$timeout'];
function expansionPanelExpandedDirective($animateCss, $timeout) {

var directive = {
restrict: 'E',
require: '^^mdExpansionPanel',
link: link
compile: compile
};
return directive;

function compile(element, attrs) {
var innerTemplate;

function link(scope, element, attrs, expansionPanelCtrl) {
var setHeight = attrs.height || undefined;
if (setHeight !== undefined) { setHeight = setHeight.replace('px', '') + 'px'; }

expansionPanelCtrl.registerExpanded({
show: show,
hide: hide,
setHeight: setHeight !== undefined,
$element: element
});
if (attrs.lazyRender !== undefined) {
element.children().attr("ng-cloak", "");
innerTemplate = element.html();
element.empty();
}

return link;

function link(scope, element, attrs, expansionPanelCtrl) {
var setHeight = attrs.height || undefined;
if (setHeight !== undefined) { setHeight = setHeight.replace('px', '') + 'px'; }

expansionPanelCtrl.registerExpanded({
show: show,
hide: hide,
setHeight: setHeight !== undefined,
$element: element,
innerTemplate: innerTemplate
});

function hide(options) {
var height = setHeight ? setHeight : element[0].scrollHeight + 'px';
element.addClass('md-hide md-overflow');
element.removeClass('md-show md-scroll-y');

var animationParams = {
from: {'max-height': height, opacity: 1},
to: {'max-height': '48px', opacity: 0}
};
if (options.animation === false) { animationParams.duration = 0; }
$animateCss(element, animationParams)
.start()
.then(function () {
element.css('display', 'none');
element.removeClass('md-hide');
});
}


function show(options) {
element.css('display', '');
element.addClass('md-show md-overflow');
// use passed in height or the contents height
var height = setHeight ? setHeight : element[0].scrollHeight + 'px';

var animationParams = {
from: {'max-height': '48px', opacity: 0},
to: {'max-height': height, opacity: 1}
};
if (options.animation === false) { animationParams.duration = 0; }
$animateCss(element, animationParams)
.start()
.then(function () {

// if height was passed in then set div to scroll
if (setHeight !== undefined) {
element.addClass('md-scroll-y');
} else {
// safari will animate the max-height if transition is not set to 0
element.css('transition', 'none');
element.css('max-height', 'none');
// remove transition block on next digest
$timeout(function () {
element.css('transition', '');
}, 0);
}

element.removeClass('md-overflow');
});
function hide(options) {
var height = setHeight ? setHeight : element[0].scrollHeight + 'px';
element.addClass('md-hide md-overflow');
element.removeClass('md-show md-scroll-y');

var animationParams = {
from: {'max-height': height, opacity: 1},
to: {'max-height': '48px', opacity: 0}
};
if (options.animation === false) { animationParams.duration = 0; }
$animateCss(element, animationParams)
.start()
.then(function () {
element.css('display', 'none');
element.removeClass('md-hide');
});
}


function show(options) {
element.css('display', '');
element.addClass('md-show md-overflow');
// use passed in height or the contents height
var height = setHeight ? setHeight : element[0].scrollHeight + 'px';

var animationParams = {
from: {'max-height': '48px', opacity: 0},
to: {'max-height': height, opacity: 1}
};
if (options.animation === false) { animationParams.duration = 0; }
$animateCss(element, animationParams)
.start()
.then(function () {

// if height was passed in then set div to scroll
if (setHeight !== undefined) {
element.addClass('md-scroll-y');
} else {
// safari will animate the max-height if transition is not set to 0
element.css('transition', 'none');
element.css('max-height', 'none');
// remove transition block on next digest
$timeout(function () {
element.css('transition', '');
}, 0);
}

element.removeClass('md-overflow');
});
}
}
}



}

0 comments on commit 3a05859

Please sign in to comment.