Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign upfunction templateUrl not $eval attributes? #7466
Comments
|
When the templateUrl function runs, this is before interpolation happens (interpolation is actually a directive which is linked at priority 100). I'm sure this is documented somewhere, but I'm not sure which page, so we should probably fix that in the docs and make it easier to find. Anyways, interpolation during the templateUrl function does not help a lot, because you don't have a scope just yet. But if you want to, you could do something like this: angular
.module('app', [])
.directive('drFoo', ['$interpolate', '$rootScope',
function ($interpolate, $rootScope) {
return {
templateUrl: function (e, attr) {
var template = $interpolate(attr.template)($rootScope);
console.log(template); // => test.html
return template;
}
};
}
]);<div ng-app="app" ng-init="template = 'foo.html'">
<div dr-foo template="{{ template }}"></div>
</div>Here's an example http://plnkr.co/edit/8elM4ip1b7RccIhrEQBj?p=preview |
this doesn't work.. |
Doesn't work too. |
|
@alexey-sh, as explained by @caitp, at the time the template/templateUrl functions are executed, there is no scope for the directive to interpolate against, thus interpolation can't help you with the template. The reason why manual interpolation doesn't work in your example is that you are interpolating against the Interpolation won't serve you well for specifying a template dynamically. |
|
@gkalpak @caitp Your explanation is awesome, thanks. |
|
@alexey-sh, I don't think it is a common usecase at all. TBH, a directive which does not control its own template (i.e. it receives it externally as an interpolated value) sounds like a pretty bad idea. |
|
I would publish my use-case: Imagine we have a big component, for example a TOS, or a long form that has 2 states: editable, or read-only. (Since we are on github, imagine opening README in read or write mode) This state rw/ro can be passed as a simple attribute A workaround for that would be create a |
|
This should definitely be added. Being able to use bound values to determine template content is extremely valuable. |
|
FWIW, @colthreepv,
Then, within an ng-repeat on
|
|
Looking at the source, it shouldn't be too difficult to delay evaluation of the templateUrl to the nodeLinkFn and be able to inject the evaluated properties. The usage should look something like: templateUrl: function($element, $attrs, $bindings){
//$attrs.property should be the usage string literal
//$bindings.property should be the isolated scope reference instead.
},
bindings: {
property: '='
}, |
|
@caitp it doesn't work for components at all though. Looking at source the templateUrl function is executed at the registerComponent phase. If i am reading the source right, the $compile phase is the point at which the bindings are actually evaluated, which is far too late. It seems that evaluating bindings before attempting to determine the template is not trivial to change at this point. |
|
@timothyswt , bindings are evaluated after the compile phase (during the linking phase, right before controllers are instantiated). The template has to fetched before the compile phase (you can't compile the template until you have a template). But there are several ways around this if you must (e.g. |
|
@gkalpak hopefully Angular 2 will avoid this sort of pattern and follow more of a react-style evaluation of bindings so that we can have more dynamic components |
Hi,
Attributes not $eval when use function in templateUrl.
Here example:
jsfiddle
It reproduced in v1.2.16 and v1.3.0-beta8