-
Notifications
You must be signed in to change notification settings - Fork 6.7k
Should the directives support variable templateUrls? #1611
Comments
@joshkurz There is a "hackish" way to configure templateUrl dynamically as mentioned #743 (comment). |
ahh yes that is hackish. Since this has been a topic of debate for a while now, I dont want to beat a dead horse, but I really feel that with >1.1.x the ability to use variable template urls is as easy as: templateUrl: function(tElem,tAttrs){
if(tAttrs.templateUrl){
return templateUrl;
} else {
return defaultPath;
}
}, This could save people a lot of time when using these directives without having to take hackish steps or messing with the build. |
I can't stop thinking that this whole problem is artificial, since templates should be preloaded in the $temaplateCache anyways. Maybe we should change those paths to something abstract, like '$templates/alert.html' so people understand that those paths shouldn't be used to download real files... I'm kind of tired with this topic as I fail to see what is the real problem and don't know how to make people aware of the fact that those paths are not real paths.... |
@pkozlowski-opensource Agree, but a valid use case IMO is if I have 2 templates for one directive, both in the |
@bekos right, but what you are talking about is different topic, that is, using a different template per directive usage / instance, which I agree is an important topic, but I feel like this should be coming from AngularJS itself. @joshkurz was mentioning "playing with Bower", which lead me to think that this is about overriding default templates. @joshkurz what is your real concern? |
@pkozlowski-opensource Nope. I mean for example the same datepicker template for every datepicker in my application, but becuase I can have only one build file for all the user's of my application, I want it to hold both templates, and each user will use the appropriate one based on some config. Do I make sense? |
i am saying that the user should be able to use whatever templateUrl they please from the markup itself, rather than hacking js to do so. "Angular Zen" I mentioned playing with Bower just as one use case, but i feel the use case @bekos brought up is similar. Both are solved by using a function of this sort to return the templateUrl. |
@bekos @joshkurz sorry guys, I'm slow today... Let me list the use-cases I'm aware off:
@bekos I'm not sure what you mean by "user" - do you mean that different users interacting with an application should see different set of templates (that is - different widgets?). Is it a real use case? @joshkurz I'm still not clear what is the exact thing you are after... Is it one of the use-cases I've listed above or something else? If this is something else, could you please be more specific / provide more details? |
@pkozlowski-opensource I will try to explain with simple, step-by-step example to help you :-P Let's say I have the So in my build file I have something like this: angular.module("template/accordion/accordion.html", []).run(["$templateCache", function($templateCache) {
// White
$templateCache.put("template/accordion/accordion.html",
"<div class=\"panel-group\" ng-transclude></div>");
// Black
$templateCache.put("template/accordion/accordion-black.html",
"<div class=\"panel-group-black\" ng-transclude></div>");
}]); Now when user John Doe uses my application to show the black template, but when Jane Roe uses it to show the white one :-) So when my application initializes I want to do something naive like: app.run(
if (user === 'John Doe') {
accordion.template = 'template/accordion/accordion-black';
} else if (user === 'Jane Roe') {
accordion.template = 'template/accordion/accordion';
}
); So as long as John uses my application he sees everything black, but Jane sees everything white. |
@bekos it totally makes sense now, thnx for bearing with me. This sounds like yet another use-case to have different "profiles" for different users. Not sure how common it is and if this couldn't be handled by CSS, but it doesn't sound like the issue that @joshkurz was raising. @bekos is it a real thing that you are struggling with in one of your projects or just anticipating a use-case? Somehow I would expect that your use-case would be handled with a different bootstrap CSS and wouldn't require a different set of templates, but I might be wrong. |
2 and 3 are correct. I think saying something about bower made you think i was just talking about that one case. (i should have been more descriptive). This is broader than that in my opinion, since the proposed solution solves multiple use cases.
so maybe it would look like this templateUrl: function(tElem,tAttrs){
return tAttrs.template || config.template || defaultPath;
}, |
@pkozlowski-opensource I haven't deal with this in a project but except theming case (dark/white etc) that can be solved by just changing the CSS, that will solve issues for alternative templates. For example in timepicker the arrows to be on the left/rigth of the input instead of up/down - I know this sounds silly but I couldn't think of something better :-) |
@bekos, for the use case you mentioned, using the $decorator to modify the directive actually seems like quite a decent approach. I don't think it's very hackish in a way that makes it a bad practice. It's quite maintainable too because the directive name and templateUrl properties are unlikely to change. Referring to @joshkurz 's use case 3, to me, this seems to be quite rare and unusual of a use case. I think that unless a directive explicitly deals with generating html for display (perhaps popovers is an example), it's unlikely that a user will want to specify a template url on each use of the directive. If we do go with that approach that @joshkurz mentions with the templateUrl function, I think the attribute should be prefixed with the directive name. I feel like this should be allowed through users defining their own directives (with their templateUrls). My vision on such customization is to allow users to instantiate the directives we have in this repo and customize them without copy-pasting the whole directive code. Something similar to the $tooltip service. Like:
|
@chrisirhc I called it hackish in a sense that is not known by many people. |
@bekos ah okay. Indeed and it's quite new. I like the idea though. Perhaps it should be in the FAQ, or StackOverflow as a wiki. And we should know about it if someone asks, heh. |
+1 for adding in the FAQ. |
thats not a bad idea at all @chrisirhc. I kinda like it. Never thought about overwriting directive definition objects based off of the return values of some directive service. (could be overkill though for simple use cases) I do feel that the solution for 2 is a little hacky as it makes the controller the source of truth for the directive's template. i believe there is no benefit to hardcoding the templateUrls, because making them dynamic solves these use cases for little cost. So is there a benefit? |
I think the current way of doing things is just to keep things short and simple. My concern is weighing the need for this functionality over more code to maintain. We can even use a service / value provider for the templateUrl:
This way the behavior can be overridden. I'm just quite on the fence on this. I think the real issue is perhaps knowing what majority of users want or need. |
Agree 100% From what i've seen in other threads people do want this, but its not until now that its possible to offer it with a simple implementation. This can be accomplished in simple manageable ways now with AngularJS>1.2.x as shown by examples on this thread. I dont feel it makes things complex by any means. The ability for users to define templates (templateCached or not) in their semantic markup or some js config is very powerful. IMO |
I need the ability to have different markup for some tabs on a page by page basis. Injecting templates with the script tag on each page is getting ugly. This topic was recently brought up again in angular-ui#1611. @sudhakar mentions a similar need for this in angular-ui#105. _Usage_ ```html <tabset> <tab ng-repeat="tab in tabs"> <tabset template-url="custom_tab_template"> <tab ng-repeat="innerTab in tab.tabs"> <span class="inner-tab-content">{{ innerTab.content }}</span> </tab> </tabset> </tab> </tabset> ```
I need the ability to have different markup for some tabs on a page by page basis. Injecting templates with the script tag on each page is getting ugly. This topic was recently brought up again in angular-ui#1611. @sudhakar mentions a similar need for this in angular-ui#105. Usage <tabset> <tab ng-repeat="tab in tabs"> <tabset template-url="custom_tab_template"> <tab ng-repeat="innerTab in tab.tabs"> <span class="inner-tab-content">{{ innerTab.content }}</span> </tab> </tabset> </tab> </tabset>
I need the ability to have different markup for some tabs on a page by page basis. Injecting templates with the script tag on each page is getting ugly. This topic was recently brought up again in angular-ui#1611. @sudhakar mentions a similar need for this in angular-ui#105. Usage <tabset> <tab ng-repeat="tab in tabs"> <tabset template-url="custom_tab_template"> <tab ng-repeat="innerTab in tab.tabs"> <span class="inner-tab-content">{{ innerTab.content }}</span> </tab> </tabset> </tab> </tabset>
I need the ability to have different markup for some tabs on a page by page basis. Injecting templates with the script tag on each page is getting ugly. This topic was recently brought up again in angular-ui#1611. @sudhakar mentions a similar need for this in angular-ui#105. Usage <tabset template-url="custom_tab_template"> <tab heading="Stuff"> Some stuff here </tab> </tabset>
Hi everyone, I don't mean to stir up the water again, but I think I am facing the actual case where
The thing is, we are using the accordion directive for 2 different purposes in the same app. One is to display a set of data and the other one is because the client wanted the behavior on a FAQ kind of page. So, for the set of data, we needed to display one button that would actually toggle the accordion-group but the rest of the heading won't trigger any change (this is where we had to alter the template and use one of our own). Now for the other accordion, we want the standard behavior, where clicking anywhere on the heading will toggle the contents. Right now, we have an issue where after modifying the heading for one of the accordions, the other got changed as a side effect. I guess we could roll our own solution leveraging the collapse directive in either of the cases, but I was wondering if there could be a way to "switch" between templates. I looked into the related links posted above but wasn't able to figure out what I am trying to accomplish. |
Thanks a lot @RobJacobs, I didn't go back to the docs after implementing the accordions a couple weeks ago. Awesome timing! |
I know that it would be a simple change to allow for the directives in this repo to offer variable templates based off of the markup. As of now, the directives are hardcoded with specific urls, making it a little difficult to plug and play with Bower.
update: it also makes it impossible to use the same directive with different templates.
Here is an issue angular/angular.js#5867 brought up, which would allow for overwriting urls in $templateProvider. I believe that the templateUrls should be optionally overwritten by some attribute on the directive itself.
Is this something that you guys are looking at doing or is the templateUrl hardcoded in the directives for a reason i'm not aware of?
The text was updated successfully, but these errors were encountered: