Skip to content
This repository has been archived by the owner on Sep 5, 2024. It is now read-only.

Commit

Permalink
fix(sticky): compile cloned element in the same scope
Browse files Browse the repository at this point in the history
Currently never apply a scope to the cloned element, which will cause problems with directives, which have bindings in their template.

Also added the documentation for a common use-case

Closes #4979. Closes #7151.
  • Loading branch information
devversion authored and ThomasBurleson committed Feb 23, 2016
1 parent 1d8fc16 commit 76d89c7
Showing 1 changed file with 45 additions and 2 deletions.
47 changes: 45 additions & 2 deletions src/components/sticky/sticky.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,53 @@ angular
* @description
* The `$mdSticky`service provides a mixin to make elements sticky.
*
* By default the `$mdSticky` service compiles the cloned element in the same scope as the actual element lives.
*
* <h3>Notes</h3>
* When using an element which is containing a compiled directive, which changed its DOM structure during compilation,
* you should compile the clone yourself using the plain template.<br/><br/>
* See the right usage below:
* <hljs lang="js">
* angular.module('myModule')
* .directive('stickySelect', function($mdSticky, $compile) {
* var SELECT_TEMPLATE =
* '<md-select ng-model="selected">' +
* '<md-option>Option 1</md-option>' +
* '</md-select>';
*
* return {
* restrict: 'E',
* replace: true,
* template: SELECT_TEMPLATE,
* link: function(scope,element) {
* $mdSticky(scope, element, $compile(SELECT_TEMPLATE)(scope));
* }
* };
* });
* </hljs>
*
* @usage
* <hljs lang="js">
* angular.module('myModule')
* .directive('stickyText', function($mdSticky, $compile) {
* return {
* restrict: 'E',
* template: '<span>Sticky Text</span>',
* link: function(scope,element) {
* $mdSticky(scope, element);
* }
* };
* });
* </hljs>
*
* @returns A `$mdSticky` function that takes three arguments:
* - `scope`
* - `element`: The element that will be 'sticky'
* - `elementClone`: A clone of the element, that will be shown
* when the user starts scrolling past the original element.
* If not provided, it will use the result of `element.clone()`.
*/
function MdSticky($document, $mdConstant, $$rAF, $mdUtil) {
function MdSticky($document, $mdConstant, $$rAF, $mdUtil, $compile) {

var browserStickySupport = checkStickySupport();

Expand All @@ -51,7 +90,11 @@ function MdSticky($document, $mdConstant, $$rAF, $mdUtil) {
contentCtrl.$element.data('$$sticky', $$sticky);
}

var deregister = $$sticky.add(element, stickyClone || element.clone());
// Compile our clone element in the given scope if the stickyClone has no scope predefined.
var cloneElement = stickyClone && stickyClone.scope && stickyClone.scope() ?
stickyClone : $compile(stickyClone || element.clone())(scope);

var deregister = $$sticky.add(element, cloneElement);
scope.$on('$destroy', deregister);
}
};
Expand Down

0 comments on commit 76d89c7

Please sign in to comment.