diff --git a/lib/angular.dart b/lib/angular.dart
index 006803185..769e34ba2 100644
--- a/lib/angular.dart
+++ b/lib/angular.dart
@@ -37,6 +37,7 @@ part 'node_cursor.dart';
part 'parser.dart';
part 'scope.dart';
part 'selector.dart';
+part 'string_utilities.dart';
ASSERT(condition) {
if (!condition) {
diff --git a/lib/block.dart b/lib/block.dart
index 008e78519..7a4dd4cf6 100644
--- a/lib/block.dart
+++ b/lib/block.dart
@@ -318,7 +318,7 @@ class ComponentFactory {
createAttributeMapping(Scope parentScope, Scope shadowScope, Parser parser) {
directive.$map.forEach((attrName, mapping) {
- var attrValue = element.attributes[attrName];
+ var attrValue = element.attributes[snake_case(attrName, '-')];
if (attrValue == null) attrValue = '';
if (mapping == '@') {
shadowScope[attrName] = attrValue;
diff --git a/lib/string_utilities.dart b/lib/string_utilities.dart
new file mode 100644
index 000000000..846e81f4a
--- /dev/null
+++ b/lib/string_utilities.dart
@@ -0,0 +1,7 @@
+part of angular;
+
+var SNAKE_CASE_REGEXP = new RegExp("[A-Z]");
+
+snake_case(String name, [separator = '_']) =>
+ name.replaceAllMapped(SNAKE_CASE_REGEXP, (Match match) =>
+ (match.start != 0 ? separator : '') + match.group(0).toLowerCase());
diff --git a/test/compiler_spec.dart b/test/compiler_spec.dart
index 9f470b8dc..4aff600c1 100644
--- a/test/compiler_spec.dart
+++ b/test/compiler_spec.dart
@@ -391,6 +391,7 @@ main() {
describe('components', () {
beforeEach(module((AngularModule module) {
module.directive(SimpleComponent);
+ module.directive(CamelCaseMapComponent);
module.directive(IoComponent);
module.directive(ParentExpressionComponent);
module.directive(PublishMeComponent);
@@ -412,7 +413,7 @@ main() {
it('should create a component that can access parent scope', inject(() {
$rootScope.fromParent = "should not be used";
$rootScope.val = "poof";
- var element = $('