I have an accordion with overridden template like that:
<uib-accordion-group template-url="/somefolder/accordion-group.html">
but I really want to use a scope variable for that, e.g. something like this:
<uib-accordion-group template-url="{{::urls.templateUrls.customAccordion}}">
but that does not seem to work.
Is there a way to use angular expression in template-url or it's not supported?
The code to read the template-url attribute is in the templateUrl function of the directive as shown here The template-url attribute is being evaluated before the $compile phase so the interpolation you are trying to use has not occurred yet. While the template-url evaluation could be moved to the linking phase, then the $compile phase would have to be run again against the new template and that wouldn't be a very efficient approach
Related
I want to know the difference between ng-bind-html and bind-html-compile directives. For example I gave
<p style='color:red'>test<p>
to ng-bind-html, this strips out the style where as bind-html-compile does not. May I know when each directive should be used. Thanks.
bind-html-compile is not a standard Angular directive, it comes with the module https://github.com/incuna/angular-bind-html-compile and it is used to compile binded data.To make it simple, it is equivalent to write html in your source code: it will be re-evaluated and if other directives are found, they will work as expected.
ng-bind-html is a standard directive (bundled with Angular itself) and just output html strings without compiling it.
for example, if you controller has a variable with plain html, like in:
$scope.dataToDisplay = '<h1><strong>Title</strong></h1>';
Then you can go with ng-bind-html.
If you need to inject variables that contain html with other directives, such as:
$scope.dataToDisplay = '<h1 ng-show="showIfOtherVariable"><strong>Title</strong></h1>';
then you need to aforementioned module.
I am developing a custom directive and now I need to handle ng-if. This is easy enough when ng-if is on the directive it self. However when ng-if is on an enclosing container element my compile function fails with run time errors.
Question is: what is the best and most efficient way to know, inside the compile function of a directive, that the directive is enclosed within a container with ng-if is false OR an expression that evaluates to false.
For example:
<div ng-if="false">
<my-directive></my-directive>
</div>
And another example:
<div ng-if="somescopeValue > 300">
<my-directive></my-directive>
</div>
Maybe the answer is using jquery to traverse the dom and find a parent with
an ng-if attribute but I was wondering if there is another more "angular" way of doing this.
Your directive shouldn't rely on knowing whether it is encapsulated in a ng-if expression. That breaks the principle of 'Separation of Concerns' and deteriorates code re-use. Consider redesigning your custom directive in such a way that it needs not be aware of its host elements, in the same fashion that all components (should) work.
If you are using same scope as parent controller or directive then you are able to access same variable in your directive(here my-directive) also. If this is not a case then you need to write code to access parent element in link function of my-directive. You will get directive element in link function as a parameter.
I'm not sure how the error happens, because when your directive is inside ng-if="false", your directive won't get called at all - all compile, link and controller function in the directive will only run as soon as your directive gets added in DOM.
Perhaps your error can be solved by initializing something in case your directive is not added.
See this plnkr
https://plnkr.co/edit/theggRtJlbFj1H4zVUKU?p=preview
using the $compile service, I need to have dirC nested inside dirB.
The output should be
DirB
DirC
I thought this was bug since dirC directive and controller was never fired, so the Angular group said to use transclusion.
Ok, so I use transclusion and dirC and dirB is never added to the DOM.
What am I missing?
The directive C is included inside the directive B. But the only visible text in both templates is inside the div which has the directive ng-transclude. So the textual content is replaced by the transcluded HTML: the directive C in the case if <dir-b>, and nothing in the case of <dir-c>.
Here's your example with fixed templates to show you that it works fine: https://plnkr.co/edit/FRtMA3h0Caredc4staW8?p=preview
Like ng-view, ng-transclude is a placeholder which means: replace the content of this element by the one inside the body of the directive.
Following the advise of this answer, I've been trying to render a controller and template manually, but I can't get it to work when the template contains an ng-switch directive. Any ideas?
Here's the fiddle: http://jsfiddle.net/kynZm/
It looks like the ng-switch directive was being compiled before my link function had a chance to run and was linking to the $rootScope. Moving the $compile call to the compile phase of the directive seemed to do the trick.
http://jsfiddle.net/z8uXg/
I'm new to Angular JS. In my plunkr, I have a typeahead that works when I have the typeahead in the html markup. However, when I dynamically generate the html inside my directive, the typeahead no longer works.
Code Here:
http://plnkr.co/edit/KdrxptYAnpTmKa7ZuKkM?p=preview
and to take it one step further, when I pass in a function, it still does not work:
http://plnkr.co/edit/jqN913hJxuVSFAZxAQt7?p=preview
It is not a trivial problem you are trying to solve here, I'm afraid. Basically you are bumping into the scoping issue. The typeahead directive evaluates it expression (city for city in cities($viewValue) here) in the scope of the DOM element on which it is placed. The way you written your wrapper directive makes it so the expression is evaluated in the directive's scope which is isolated and doesn't "see" your controllers scope.
The are number of ways around it but probably the simplest one is to link your $compiled-ed element in the scope that is $parent of your directive scope:
var linkedInput = $compile(inputHtml)(scope.$parent);
Here is a working plunk: http://plnkr.co/edit/fLFwIKNqIRbnesMjZBGj?p=preview
The other alternative is to loose an isolated scope and "manually" take care of the 2-way data binding with the help from the $parse service.