I'm using ng-repeat and I need to pass a scope variable into a directive's compile function. I know how to do it with the link function, but not the compile function.
My html looks like:
<div ng-repeat="item in chapter.main">
<block type="item.type"></block>
</div>
Let's say item.type="blah" no matter the item. Then this link function works fine
app.directive('block', function() {
return {
restrict: 'E',
link: function(scope, element, attributes){
scope.$watch(attributes.type, function(value){
console.log(value); //will output "blah" which is correct
});
}
}
});
But I can't do the same with compile?
app.directive('block', function() {
return {
restrict: 'E',
compile: function(element, attrs, scope) {
scope.$watch(attrs.type, function(value){
console.log(value);
});
}
}
});
The error I get is "cannot read property $watch of undefined"..
This is how I'd like my directive to look like:
app.directive('block', function() {
return {
restrict: 'E',
compile: function(element, attrs) {
element.append('<div ng-include="\'{{type}}-template.html\'"></div>');
//or element.append('<div ng-include="\'{' + attrs.type + '}-template.html\'"></div>');
//except the above won't interpret attr.type as a variable, just as the literal string 'item.type'
}
}
});
The compile function doesn't have scope as one it's parameter.
function compile(tElement, tAttrs, transclude) { ... }
NOTE: transclude is deprecated in the latest version of Angular.
Is there any reason you don't want to use link?
From the DOC
The compile function deals with transforming the template DOM. Since most directives do not do template transformation, it is not used often. The compile function takes the following arguments:
tElement - template element - The element where the directive has been declared. It is safe to do template transformation on the element and child elements only.
tAttrs - template attributes - Normalized list of attributes declared on this element shared between all directive compile functions.
transclude - [DEPRECATED!] A transclude linking function: function(scope, cloneLinkingFn)
UPDATE
To access the scope from inside compile function, you need to have either a preLink or postLink function. In your case, you need only the postLink function. So this ...
compile: function compile(tElement, tAttrs, transclude) {
return function postLink(scope, element, attrs) { ... }
},
PROPOSED SOLUTION Might not be exact but should help you on your way.
html
<div ng-app="myApp" ng-controller="app">
<block type="item.type"></block>
</div>
JS (Controller + Directive)
var myApp = angular.module('myApp', []);
myApp.controller('app', function ($scope, $http) {
$scope.item = {
type: 'someTmpl'
};
}).directive('block', ['$compile', function ($compile) {
return {
restrict: 'AE',
transclude: true,
scope: {
type: '='
},
compile: function (element, attrs) {
return function (scope, element, attrs) {
var tmpl;
tmpl = scope.type + '-template.html';
console.log(tmpl);
element.append('<div ng-include=' + tmpl + '></div>');
$compile(element.contents())(scope);
};
}
};
}]);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With