Don't use "data" prefix in AngularJS
2017-08-10 16:41
I lost a couple of hours over this. When creating a directive or attribute name in AngularJS that will be "kebab-cased," do not prefix it with data
, such dataFn
or dataFromApi
. It becomes data-fn
or data-from-api
and won't work because data-
is reserved by javascript for values.
Note: I'm taking a hard line, here. Such a name might work in some cases--but definitely doesn't when trying to invoke an expression passed to an isolate-scope directive.
This will work.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.min.js"></script>
</head>
<body ng-app="app">
<div ng-controller="MyController as vm">
<button ng-click="vm.alert()">From Body</button>
<my-directive fn="vm.alert()"></my-directive>
</div>
</body>
</html>
<script>
angular.module('app',['MyModule']);
angular.module('MyModule', [])
.controller('MyController', MyController)
.directive('myDirective', myDirective);
function MyController(){
var vm = this;
vm.alert = function(){alert('alert');}
}
function myDirective() {
var directive = {
scope: {
fn: '&'
},
template: "<button ng-click='fn()'>From Directive</button>"
}
return directive;
}
</script>
This won't work, because data-
is reserved by javascript.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.min.js"></script>
</head>
<body ng-app="app">
<div ng-controller="MyController as vm">
<button ng-click="vm.alert()">From Body</button>
<!-- data-fn WILL NOT WORK -->
<my-directive data-fn="vm.alert()"></my-directive>
</div>
</body>
</html>
<script>
angular.module('app',['MyModule']);
angular.module('MyModule', [])
.controller('MyController', MyController)
.directive('myDirective', myDirective);
function MyController(){
var vm = this;
vm.alert = function(){alert('alert');}
}
function myDirective() {
var directive = {
scope: {
dataFn: '&'
},
template: "<button ng-click='dataFn()'>From Directive</button>"
}
return directive;
}
</script>
This works, using the non-reserved my-
prefix.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.min.js"></script>
</head>
<body ng-app="app">
<div ng-controller="MyController as vm">
<button ng-click="vm.alert()">From Body</button>
<!-- my-fn WORKS -->
<my-directive my-fn="vm.alert()"></my-directive>
</div>
</body>
</html>
<script>
angular.module('app',['MyModule']);
angular.module('MyModule', [])
.controller('MyController', MyController)
.directive('myDirective', myDirective);
function MyController(){
var vm = this;
vm.alert = function(){alert('alert');}
}
function myDirective() {
var directive = {
scope: {
myFn: '&'
},
template: "<button ng-click='myFn()'>From Directive</button>"
}
return directive;
}
</script>