Reputation: 3614
I have a web app with directives in which the template url is build through a factory, but sometimes I also need the value of one of the attributes, so I do something like this:
myDirective.$inject = ['myFactory'];
function myDirective(myFactory) {
return {
restrict: 'E',
replace: true,
scope: {},
bindToController: {
...
},
controller: myDirectiveController,
templateUrl: function(elem, attrs) {
return angular.isDefined(attrs.myval) ? myFactory.url() : myFactory.altUrl();
}
}
}
Now, I'm changing a few of these to components, and I didn´t manage to do the same, as now components are objects instead of functions.
I can do without using attrs, like this
angular.component('myDirective', {
bindings: {
...
},
controller: 'myDirectiveController as vm',
templateUrl: function(myFactory) {
return myFactory.url();
}
}
but if I try to use also the attrs
angular.component('myDirective', {
bindings: {
...
},
controller: 'myDirectiveController as vm',
templateUrl: function(elem, attrs, myFactory) {
return angular.isDefined(attrs.myval) ? myFactory.url() : myFactory.altUrl();
}
}
I get an angular error. Any idea on how to do this?
Upvotes: 3
Views: 2433
Reputation: 1622
This is because with a component
, templateUrl
became an injectable function:
If
templateUrl
is a function, then it is injected with the following locals:
$element
- Current element
$attrs
- Current attributes object for the element
This means you can inject $element
and $attrs
like any other service, factory, value, etc. you would inject into the templateUrl
. This is instead of just receiving the element
and attrs
as always the first 2 parameters (that can be named anything), like the templateUrl
in a directive
:
Directive:
templateUrl: function(tElement, tAttrs)
Component:
templateUrl: function(someService, $attrs, $element, someOtherService)
By this logic, in the example you showed above, the error is coming from the fact that angular can't find a service or local with the name elem
or attrs
.
Upvotes: 6