diff --git a/src/components/sidenav/sidenav.js b/src/components/sidenav/sidenav.js
index cbd2a4ccbb3..4005b782624 100644
--- a/src/components/sidenav/sidenav.js
+++ b/src/components/sidenav/sidenav.js
@@ -249,8 +249,7 @@ function SidenavDirective($mdMedia, $mdUtil, $mdConstant, $mdTheming, $animate,
},
controller: '$mdSidenavController',
compile: function(element) {
- element.addClass('md-closed');
- element.attr('tabIndex', '-1');
+ element.addClass('md-closed').attr('tabIndex', '-1');
return postLink;
}
};
@@ -481,9 +480,8 @@ function SidenavDirective($mdMedia, $mdUtil, $mdConstant, $mdTheming, $animate,
* @ngdoc controller
* @name SidenavController
* @module material.components.sidenav
- *
*/
-function SidenavController($scope, $element, $attrs, $mdComponentRegistry, $q) {
+function SidenavController($scope, $attrs, $mdComponentRegistry, $q, $interpolate) {
var self = this;
@@ -505,5 +503,21 @@ function SidenavController($scope, $element, $attrs, $mdComponentRegistry, $q) {
self.toggle = function() { return self.$toggleOpen( !$scope.isOpen ); };
self.$toggleOpen = function(value) { return $q.when($scope.isOpen = value); };
- self.destroy = $mdComponentRegistry.register(self, $attrs.mdComponentId);
+ // Evaluate the component id.
+ var rawId = $attrs.mdComponentId;
+ var hasDataBinding = rawId && rawId.indexOf($interpolate.startSymbol()) > -1;
+ var componentId = hasDataBinding ? $interpolate(rawId)($scope.$parent) : rawId;
+
+ // Register the component.
+ self.destroy = $mdComponentRegistry.register(self, componentId);
+
+ // Watch and update the component, if the id has changed.
+ if (hasDataBinding) {
+ $attrs.$observe('mdComponentId', function(id) {
+ if (id && id !== self.$$mdHandle) {
+ self.destroy(); // `destroy` only deregisters the old component id so we can add the new one.
+ self.destroy = $mdComponentRegistry.register(self, id);
+ }
+ });
+ }
}
diff --git a/src/components/sidenav/sidenav.spec.js b/src/components/sidenav/sidenav.spec.js
index 3449a94e61d..3ea49b15717 100644
--- a/src/components/sidenav/sidenav.spec.js
+++ b/src/components/sidenav/sidenav.spec.js
@@ -1,14 +1,14 @@
describe('mdSidenav', function() {
beforeEach(module('material.components.sidenav'));
- function setup(attrs) {
+ function setup(attrs, skipInitialDigest) {
var el;
inject(function($compile, $rootScope) {
var parent = angular.element('
');
el = angular.element('');
parent.append(el);
$compile(parent)($rootScope);
- $rootScope.$apply();
+ !skipInitialDigest && $rootScope.$apply();
});
return el;
}
@@ -168,13 +168,13 @@ describe('mdSidenav', function() {
describe('controller', function() {
it('should create controller', function() {
- var el = setup('');
+ var el = setup();
var controller = el.controller('mdSidenav');
expect(controller).not.toBe(undefined);
});
it('should open and close and toggle', inject(function($timeout) {
- var el = setup('');
+ var el = setup();
var scope = el.isolateScope();
var controller = el.controller('mdSidenav');
@@ -213,7 +213,7 @@ describe('mdSidenav', function() {
}));
it('should open(), close(), and toggle() with promises', function() {
- var el = setup('');
+ var el = setup();
var scope = el.isolateScope();
var controller = el.controller('mdSidenav');
@@ -257,7 +257,7 @@ describe('mdSidenav', function() {
});
it('should open() to work multiple times before close()', function() {
- var el = setup('');
+ var el = setup();
var controller = el.controller('mdSidenav');
var openDone = 0, closeDone = 0;
@@ -351,23 +351,35 @@ describe('mdSidenav', function() {
});
describe('$mdSidenav lookups', function() {
- var $rootScope, $timeout;
+ var $rootScope, $timeout, $mdSidenav;
- beforeEach(inject(function(_$rootScope_, _$timeout_) {
+ beforeEach(inject(function(_$rootScope_, _$timeout_, _$mdSidenav_) {
$rootScope = _$rootScope_;
$timeout = _$timeout_;
+ $mdSidenav = _$mdSidenav_;
}));
- it('should find an instantiation using `$mdSidenav(id)`', inject(function($mdSidenav) {
+ it('should find an instantiation using `$mdSidenav(id)`', function() {
var el = setup('md-component-id="left"');
$timeout.flush();
// Lookup instance still available in the component registry
var instance = $mdSidenav('left');
expect(instance).toBeTruthy();
- }));
+ });
- it('should find a deferred instantiation using `$mdSidenav(id, true)`', inject(function($mdSidenav) {
+ it('should support data bindings', function() {
+ // It should work on init.
+ $rootScope.leftComponentId = 'left';
+ setup('md-component-id="{{ leftComponentId }}"', true);
+ expect($mdSidenav($rootScope.leftComponentId, false)).toBeTruthy();
+
+ // It should also work if the data binding has changed.
+ $rootScope.$apply('leftComponentId = "otherLeft"');
+ expect($mdSidenav($rootScope.leftComponentId, false)).toBeTruthy();
+ });
+
+ it('should find a deferred instantiation using `$mdSidenav(id, true)`', function() {
var instance;
// Lookup deferred (not existing) instance
@@ -386,9 +398,9 @@ describe('mdSidenav', function() {
// Lookup instance still available in the component registry
instance = $mdSidenav('left', true);
expect(instance).toBeTruthy();
- }));
+ });
- it('should find a deferred instantiation using `$mdSidenav().waitFor(id)` ', inject(function($mdSidenav) {
+ it('should find a deferred instantiation using `$mdSidenav().waitFor(id)` ', function() {
var instance;
// Lookup deferred (not existing) instance
@@ -409,9 +421,9 @@ describe('mdSidenav', function() {
instance = $mdSidenav('left');
expect(instance).toBeTruthy();
- }));
+ });
- it('should not find a lazy instantiation without waiting `$mdSidenav(id)`', inject(function($mdSidenav) {
+ it('should not find a lazy instantiation without waiting `$mdSidenav(id)`', function() {
var instance = $mdSidenav('left');
expect(instance.isOpen).toBeDefined(); // returns legacy API with noops
@@ -425,9 +437,9 @@ describe('mdSidenav', function() {
instance = $mdSidenav('left'); // returns instance
expect(instance).toBeDefined();
expect(instance.isOpen()).toBeFalsy();
- }));
+ });
- it('should not find a lazy instantiation without waiting `$mdSidenav().find(id)`', inject(function($mdSidenav) {
+ it('should not find a lazy instantiation without waiting `$mdSidenav().find(id)`', function() {
var instance = $mdSidenav().find('left');
expect(instance).toBeUndefined();
@@ -438,7 +450,7 @@ describe('mdSidenav', function() {
instance = $mdSidenav().find('left');
expect(instance).toBeDefined();
expect(instance.isOpen()).toBeFalsy();
- }));
+ });
describe('onClose', function () {
it('should call callback on escape', inject(function($mdSidenav, $rootScope, $material, $mdConstant, $timeout) {