-
Notifications
You must be signed in to change notification settings - Fork 27.4k
Feature: Either add scope to attributes that are passed to templateUrl function or preprocess attributes based on scope parameters #2895
Comments
As part of our effort to clean out old issues, this issue is being automatically closed since it has been inactivite for over two months. Please try the newest versions of Angular ( Thanks! |
+1 to this feature request. Not being able to access scope from |
Yes, please reopen this issue, it is still a missing feature. |
This is still a missing feature. |
This should be reopened. Either scope should be accessible as an attribute of the templateUrl function or scope bindings should be evaluated before attributes are passed to the function |
I think this is a similar issue to issue #1039, and essentially it boils down to the compileTemplateUrl being called before the scope is available. Please merge these issues. |
I'm struggling with this issue from two days, please reopen this issue. |
@jimmywarting Yes you could do something like this, but that requires 2 compiles when only one should be needed. A directive should be self contained, not requiring other core directives to be used alongside it. Technically you could do the same thing by setting the templateUrl to '/views/loader.html' with:
but that now requires 2 ajax calls and 2 child scopes when you only really needed one. Being able to grab a template type from the scope and apply it to the templateUrl dynamically is a long sought after feature that directives could benefit from, but I believe it's a "chicken before the egg" issue looking at the code myself, and would require a major revamp in the order of operations for compiling a directive. |
+1 to this request. Desperately need this feature. The ngInclude trick is not at all ideal! The same problem exists in ngRoute as well, which after all is a directive. |
+1 will be super usable to have compiled parameters in tempalteUrl function. Thanks. |
@vict-shevchenko the template function is run before scope is ever created, (so isolate scope propreties would never work) --- it would only work properly with the parent scope. I think people generally want this behaviour with isolate scope properties |
It seems that I want the same... that so but now Is not this issue about it? |
it's a terrible idea anyways |
a directive template shouldn't depend on anything like that. |
Ok, can you then point me to a proper solution of the issue? My need is in dynamically change templateUrl based on parent scope parameters, that I can pass to a directive attributes. Me situation is next, there is a directive that based on 'id' and 'type' (8 different types) displays some data. For each 'type' there is a different template, but same controller can be used. So I think directive that can dynamically load proper html based on 'type' is a good idea. my current solution is
is it also terrible by its nature? What approach you recommend to follow in such cases? Thanks. |
i recommend that you don't do this and instead use structural directives like ng-if or ng-switch or ng-include |
Thanks, will keep it in mind. |
@caitp this is a feature request because it doesn't make sense to me to have to rely on core directives or multiple ajax calls/scopes to make this work, can you elaborate your position? |
it does make sense for you to rely on structural directives for this. what doesn't make sense is having a crazily dynamic behaviour that is hard to keep control of. |
ng-switch from 8 elements looks crazy. keeping track of behavior is my problem actually. You guys already did support for function in templateUrl, so it already gives some space for dynamically change it. With possibility to access real values from parent scope it will be even be more powerful. That is why I`d like to +1 for this feature request. |
If the purpose of a directive is to modularize functionality, we've been given the native ability to generate a templateUrl based on a function which receives only undigested element attributes. It may be difficult to change the functionality over to allow access to the scope, but it certainly makes more sense than to "stop there". |
this request is not a good idea, this would be damaging to modularity |
structural directives need to be dynamic like this, and don't need to have specific interactions with their templates --- but components should definitely never need to do this, and if they do, they should do it using structural directives instead |
... So, this isn't a good feature because |
I'm not exactly sure why dynamic templates are such a bad idea. If there is a directive that has the same logic but presents in different ways visually, why would you want to duplicate that logic into multiple directives? I don't like having to duplicate logic or to have to use control mechanisms in my HTML templates except where it really is necessary. Can you unpack why this is such a bad idea and hurts modularity please? |
templates can (and do) contain logic and behaviour, not just presentation. Your directive should know exactly what it's going to have under the hood, and if it really can't know (ie, ui-view for instance), it should behave as a proper structural directive. Components (say a custom button or a header or something) should know what their DOM is going to look like ahead of time. Template functions allow a few things, like requesting a slightly different template URL depending on the deployment url (say I want to serve a different url depending on whether I'm hosted from gh-pages or from localhost, eg for a slide show). They can also serve different templates based on app configuration, which was proposed for ui-bootstrap last year. They basically let you configure an app for different deployments, or other things which are basically static, but you don't necessarily know ahead of time. They might want to use an attribute value, but this behaviour should be static, not runtime-changeable. Trying to do too much dynamic stuff in the template and template URL functions is just going to create more headaches than anything else. Yes, it would be a powerful feature, but not necessarily a useful one. The usefulness of it is greatly exaggerated by people who are most likely trying to solve the wrong problem with the wrong tool. (No offense, we've all done this.) In order to keep your app manageable, you should definitely minimize how dynamic your directives can be. Configuring templates (attached to behaviour) are going to be a nightmare, but if you really want to do that, ng-include already exists. ng-switch already exists. That said, I don't know if anyone else agrees with me, maybe Igor thinks super-dynamic template functions are a great idea. But I feel like the end result of it is this:
I don't know if anyone else agrees with the points I'm making here, but honestly if you feel you need super-dynamic template functions, you're probably taking the wrong approach to solving your problem, and you're probably mis-identifying the problem you're trying to solve. |
Thanks for the detailed explanation, I understand what you are saying. Need to digest a little before I could say if I agree, but I appreciate the reasoning. |
@caitp Thanks for the detailed explanation, I can totally see your side of things. I can tell you that when I first started building directives in angular, the templateUrl function was one of the more confusing portions because everything else was so centered around the scope and it just didn't make sense to not be able to access the scope from it. I don't think it should be necessarily stripped out to avoid this kind of confusion, but there is nothing in the directive docs about it, and it felt like I was hunting a sasquatch in the end. |
would you like to submit a PR? |
@btford Yeah, I was planning on it, I'll submit something tonight after work. |
Adding documentation and example of using a templateUrl function to the directive developer guide. Related to angular#2895
@caitp I disagree on most points, not being able to use what seems like a basic feature
I am not even sure if this feature would harm performance but so far I believe readability and reducing maintenance costs are more important factors. I agree on the fact that this is not needed in most applications but cases where this missing feature is glaring and simply difficult to work with do exist:
So far ng-include kind of works but it comes with its own problems and it adds unnecessary complexity, blunder and boilerplate to something that could be solved in one line: Not to be a kill joy, but one of the reasons angular's learning curve is so bumpy is due to this type of exceptions. Angular promises great flexibility, but sometimes it stops short with no apparent reason but "It's better for you." requiring us to write boilerplate to get around missing features kept out for what seems like arbitrary reasons. If the impact on performance would be so damaging that this feature justifies the increased complexity to get dynamic template urls working, well... OK then... but why not add an alternate findTemplateUrl which would give access to the scope variables for those who need this? Now maybe I have overlooked something and what we need done can be achieved easily with less boilerplate across all those directives, or maybe directives are not the right tool for the job, in that case I would gladly take any advice on how I can fix this. |
I have just converted some code that was being called by ngInclude into a directive for modularity reasons. My ngInclude had a suffix which instructs the server to send the template in the correct language. I would really like to add that parameter to the templateUrl so the correct language template is loaded. This http://stackoverflow.com/a/23999356 doesn't work and this http://stackoverflow.com/a/21835866 is hacky. @caitp would love to understand what you think is the 'angular' way for my use case. Dynamic templateUrl just seems like a no brainer to me. |
+1 for this feature. Using ng-include inside a template to pass scope is an obvious cludge, and extra boilerplate is...what it is. |
@Narretz Understandable that this is marked as being in Purgatory. I haven't been keeping up with the latest in Angular 2 (currently in the middle of a big project) but has any design consideration for this been addressed within |
* pull angular-cron-gen library internally to deck to fix several issues with the library. * the latest version of the library will not allow angular expressions for the new `template-url` property as it uses the `templateUrl` function which executes before the scope is initialized so any scoped property value is not accessible. this means that our template value set via a controller property is not accessible. this is a long-standing issue [in the core library](angular/angular.js#2895) and it doesn't look to be fixed anytime soon. * an hourly cron trigger set in the UI to execute start at a specific time actually generates a daily cron expression so the portion of the hourly cron trigger that allows starting at a specific time was removed from deck's cron picker template. * the regex used by the library to match hourly cron expressions was incorrectly matching daily cron expressions which was resulting the UI displaying `hourly` instead of `daily` in the select so the regex for hourly was fixed to properly test for matching hourly cron expressions.
* pull angular-cron-gen library internally to deck to fix several issues with the library. * the latest version of the library will not allow angular expressions for the new `template-url` property as it uses the `templateUrl` function which executes before the scope is initialized so any scoped property value is not accessible. this means that our template value set via a controller property is not accessible. this is a long-standing issue [in the core library](angular/angular.js#2895) and it doesn't look to be fixed anytime soon. * an hourly cron trigger set in the UI to execute start at a specific time actually generates a daily cron expression so the portion of the hourly cron trigger that allows starting at a specific time was removed from deck's cron picker template. * the regex used by the library to match hourly cron expressions was incorrectly matching daily cron expressions which was resulting the UI displaying `hourly` instead of `daily` in the select so the regex for hourly was fixed to properly test for matching hourly cron expressions.
* pull angular-cron-gen library internally to deck to fix several issues with the library. * the latest version of the library will not allow angular expressions for the new `template-url` property as it uses the `templateUrl` function which executes before the scope is initialized so any scoped property value is not accessible. this means that our template value set via a controller property is not accessible. this is a long-standing issue [in the core library](angular/angular.js#2895) and it doesn't look to be fixed anytime soon. * an hourly cron trigger set in the UI to execute start at a specific time actually generates a daily cron expression so the portion of the hourly cron trigger that allows starting at a specific time was removed from deck's cron picker template. * the regex used by the library to match hourly cron expressions was incorrectly matching daily cron expressions which was resulting the UI displaying `hourly` instead of `daily` in the select so the regex for hourly was fixed to properly test for matching hourly cron expressions.
* pull angular-cron-gen library internally to deck to fix several issues with the library. * the latest version of the library will not allow angular expressions for the new `template-url` property as it uses the `templateUrl` function which executes before the scope is initialized so any scoped property value is not accessible. this means that our template value set via a controller property is not accessible. this is a long-standing issue [in the core library](angular/angular.js#2895) and it doesn't look to be fixed anytime soon. * an hourly cron trigger set in the UI to execute start at a specific time actually generates a daily cron expression so the portion of the hourly cron trigger that allows starting at a specific time was removed from deck's cron picker template. * the regex used by the library to match hourly cron expressions was incorrectly matching daily cron expressions which was resulting the UI displaying `hourly` instead of `daily` in the select so the regex for hourly was fixed to properly test for matching hourly cron expressions.
* pull angular-cron-gen library internally to deck to fix several issues with the library. * the latest version of the library will not allow angular expressions for the new `template-url` property as it uses the `templateUrl` function which executes before the scope is initialized so any scoped property value is not accessible. this means that our template value set via a controller property is not accessible. this is a long-standing issue [in the core library](angular/angular.js#2895) and it doesn't look to be fixed anytime soon. * an hourly cron trigger set in the UI to execute start at a specific time actually generates a daily cron expression so the portion of the hourly cron trigger that allows starting at a specific time was removed from deck's cron picker template. * the regex used by the library to match hourly cron expressions was incorrectly matching daily cron expressions which was resulting the UI displaying `hourly` instead of `daily` in the select so the regex for hourly was fixed to properly test for matching hourly cron expressions.
* pull angular-cron-gen library internally to deck to fix several issues with the library. * the latest version of the library will not allow angular expressions for the new `template-url` property as it uses the `templateUrl` function which executes before the scope is initialized so any scoped property value is not accessible. this means that our template value set via a controller property is not accessible. this is a long-standing issue [in the core library](angular/angular.js#2895) and it doesn't look to be fixed anytime soon. * an hourly cron trigger set in the UI to execute start at a specific time actually generates a daily cron expression so the portion of the hourly cron trigger that allows starting at a specific time was removed from deck's cron picker template. * the regex used by the library to match hourly cron expressions was incorrectly matching daily cron expressions which was resulting the UI displaying `hourly` instead of `daily` in the select so the regex for hourly was fixed to properly test for matching hourly cron expressions.
* pull angular-cron-gen library internally to deck to fix several issues with the library. * the latest version of the library will not allow angular expressions for the new `template-url` property as it uses the `templateUrl` function which executes before the scope is initialized so any scoped property value is not accessible. this means that our template value set via a controller property is not accessible. this is a long-standing issue [in the core library](angular/angular.js#2895) and it doesn't look to be fixed anytime soon. * an hourly cron trigger set in the UI to execute start at a specific time actually generates a daily cron expression so the portion of the hourly cron trigger that allows starting at a specific time was removed from deck's cron picker template. * the regex used by the library to match hourly cron expressions was incorrectly matching daily cron expressions which was resulting the UI displaying `hourly` instead of `daily` in the select so the regex for hourly was fixed to properly test for matching hourly cron expressions.
* pull angular-cron-gen library internally to deck to fix several issues with the library. * the latest version of the library will not allow angular expressions for the new `template-url` property as it uses the `templateUrl` function which executes before the scope is initialized so any scoped property value is not accessible. this means that our template value set via a controller property is not accessible. this is a long-standing issue [in the core library](angular/angular.js#2895) and it doesn't look to be fixed anytime soon. * an hourly cron trigger set in the UI to execute start at a specific time actually generates a daily cron expression so the portion of the hourly cron trigger that allows starting at a specific time was removed from deck's cron picker template. * the regex used by the library to match hourly cron expressions was incorrectly matching daily cron expressions which was resulting the UI displaying `hourly` instead of `daily` in the select so the regex for hourly was fixed to properly test for matching hourly cron expressions.
@vict-shevchenko I used your solution, but for components it's not possible to use the link, so I left in
Thanks for the help! |
As you can see in the following plunker, you cannot access a scoped value within the directive's templateUrl. All attributes are passed uncompiled, and there is no way to access the scope within this context. I have a workaround with a lot of dependencies injected within the link function of that directive (showing how it should work).
The text was updated successfully, but these errors were encountered: