Show which directives is being used in a page - angularjs

is there a way to show wich directives is being used in a page ?
Please, take a look at this example
<div>
some things ...
<mydirective></mydirective>
<mydirective1></mydirective1>
<mydirective2></mydirective2>
some things ...
</div>
And this is the "mydirective" html
<div>
<mychilddirective></mychilddirective>
<mychilddirective1></mychilddirective1>
<mychilddirective2></mychilddirective2>
</div>
Question 1: So, my point is, how can I show the list of directives used (like in console log or somewhere else) in this page ?
The answer for this question should be
mydirective, mychilddirective, mychilddirective1,
mychilddirective2, mydirective1, mydirective2
Question 2: If there is a answer for question 1, is there a way to "discover" the used directives using the browser console ? Or I need that my directives have to be following some kind of pattern ? (like some attribute or something like that ...)

Every directive has link functions. That are called in a sequence. You can use them to identify which directive is being used.
Here are links for more detail about link function and their calling sequence.
https://www.undefinednull.com/2014/07/07/practical-guide-to-prelink-postlink-and-controller-methods-of-angular-directives/

Related

How can my template include an element whose type is determined by an expression in angularjs?

It's 2022 and sadly I'm learning AngularJS (already past end of life!)
I need need to use what might be called a dynamic element/component. Pseudocode example:
In controller:
this.theElementName = 'b';
In the template:
<{{$ctrl.theElementName}}>this is some text</{{$ctrl.theElementName}}>
I would want this to create <b>this is some text</b>.
The reason is that I want to generate an array of different directives to render, and I don't want code like:
<b ng-if="$ctrl.theElementName === 'b'">this is some text</b>
<div ng-if="$ctrl.theElementName === 'div'">this is some text</div>
<directive-abc ng-if="$ctrl.theElementName === 'directive-abc'">this is some text</directive-abc>
...
In Svelte, it's
<svelte:element this={theElementName} />
In Vue it's
<div :is="theElementName" />
EDIT: in response to the reluctant 'that person', clarifying the use-case
Consider a user-configurable UI. The result of the configuration might be an array list of components desired. I would then need to loop and output those different components in my template. Of course the components would need a standard interface for properties passesd in, events emitted etc. but that can all be designed for.
My code could do a big switch statement, but that requires prior knowledge of every possible component that might be used now or in the future. By doing it the way I intend to, however, a future person could add a component without needing to touch this code.
You can write directive my-directive to use:
<div my-directive="$ctrl.theElementName">...
to generate:
<div><component-a>...
<div><component-b>...
<div><component-c>...
All directive should do is to generate html string and compile it:
element.append($compile('<' + scope.myDirective + '>...')(scope))
(also remember to update content in onChanges if you want to support it)
Directive may also copy certain/all attributes from original element etc.
P.S. you should be cautious e.g. if component name comes from database that may allow injections.
Not a brilliant solution, but documenting what is more of a workaround.
ng-include can be used to source another template file. That file can contain the component you need to include.
<ng-include src="'/path/to/' + theElementName + '.html'"></ng-include>

List of directives and transclusion

I'm trying to build some navigation directives to isolate complexity. I want the following HTML to render my navigation:
<custom-nav>
<nav-item>Item 1</nav-item>
<nav-item>Item 2</nav-item>
<nav-item>Item 3</nav-item>
</custom-nav>
If I wrote the directives right now, the resulting compiled HTML would look like this:
<custom-nav>
<nav>
<ul>
<nav-item><li><a>Item 1</a></li></nav-item>
<nav-item><li><a>Item 2</a></li></nav-item>
<nav-item><li><a>Item 3</a></li></nav-item>
</ul>
</nav>
</custom-nav>
however, this is invalid HTML (<ul>s can only have <li>s as children).
Without using replace: true, what is the best way for me to tackle this? The only things I can think of are:
Don't use <ul> or <li> - use aria roles to define my own list items.
Don't make the list semantically a list. I really don't want to do this.
Is there something I'm overlooking?
I am not sure if I understood the issue correctly, but what I can say is,
you can pass the items you want to use as li, in an array, as a parameter to the directive, and loop over it in your link function to generate the recommended html result, that would remove any complexity related to the issue
please let me know if I misunderstood you.
Best of luck

Show directive as result of a click

I want to show content that comes from a directive when the user clicks on a link.
<li>Show popup</li>
Obviously I'm new to angularjs. I know the approach above doesn't make sense really but I was also trying to imagine how this might be done with ng-if but not coming up with anything. Any ideas? Thanks!
Edit 1: The directive that I want to use is:
<ng-pop-up></ng-pop-up>
That's part of ngPopup.
Edit 2: This is now resolved. It turns out that in the case of ngPopup, you put the directive somewhere, then you open the dialog using the open method, so I really didn't take advantage of the solutions given here. Giving Martin credit because his solution solves problem originally stated. Thanks all.
Not exactly sure what you are looking for.
When you say, content from a directive, is this an existing directive, or do you think the content should come from a directive?
In your example where you have show popup, do you mean you would like to have a dialog displayed when you click the link?
Or do you just want something like the following example?
angular.module('app', []);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app=app>
<a href="#" ng-click='showMessage = true'>Click Here</a>
<div ng-show="showMessage">Your Message Here</div>
</div>
Try looking at using ng-if (AngularJS docs). You can use a boolean in your scope to that is toggled by the ng-click.

Angularjs : Display accolades {{ }} several milliseconds before rendering

I am going to create an application with Angularjs. I have several modals (with the ng-dialog libraries) to create, modify data like an user for example.
When I open it, I can always see during several milliseconds names variables with accolades like {{user.name}}, before it renders the real value.
It is not really beautiful and then if someone has an idea about how to manage this type of display problems, please share it.
Thank you in advance.
There are couple of ways to deal with it, you could either use ng-bind or ng-cloak directives
Check angular ngCloak directive documentation
https://docs.angularjs.org/api/ng/directive/ngCloak
You can use ng-bind. Here is the official documentation on it:
It is preferable to use ngBind instead of {{ expression }} if a template is momentarily displayed >by the browser in its raw state before Angular compiles it. Since ngBind is an element attribute, >it makes the bindings invisible to the user while the page is loading
Usage:
Hello <span ng-bind="name"></span>!

AngularJS: Updating a view with a template from a controller?

I have been working with routing and I have seen how I can update the ng-view using routing and a view template.. But the problem I have is that I am doing a REST call and depending what I get back from the response I wish to update part of the DOM with a view template but I don't want to involve routing.
Does anyone know how I can do this? Or any examples would be great
Thanks in advance
Another answer. Based on your description in the comment, it sounds like you wish to display part of the DOM conditionally.
When you want to display part of the DOM conditionally, you have the following choices:
Use an ng-show and ng-hide directive.
Based on what returns from the RESTful call, you can set up a model that will identify the DOM that needs to be displayed. An example:
<div ng-show="status">
This text will be shown only when the status is truthy
</div>
<div ng-hide="status">
This text will be shown only when the status is false.
</div>
Inside your controller, you could then set the status to true or false based on your RESTful calls and based on which part of the DOM you wish to display post RESTful call.
You can use ng-switch directive
While the ng-show and ng-hide directives will display the content of your DOM conditionally, that is anybody could simply open the source file and see the contents for both, ng-switch directive will load the contents only based on which case fulfills the swtich. An example:
<div ng-switch on="status">
<div ng-switch-when="true">
This text will be shown only when the status is truthy.
Else this is completely hidden and cannot be seen even
when looking at the source.
</div>
<div ng-switch-when="false">
This text will be shown only when the status is false.
Else this is completely hidden and cannot be seen even
when looking at the source.
</div>
</div>
The first child div is shown when the status is true else it is not shown at all. The advantage over ng-show or ng-hide is that the DOM will not contain the child elements if the case is not fulfilled.
$location.path() can be used here.
So, in your Parent Controller, you can make the REST call. Once you have the data with you, you can then decide which route to take. The route value goes into the path() function.
As an example, let us say that if your REST call returns with cherries, you need to take the /foo path (which, based on your $routeProvider will load the template associated with that route). You can then write the following:
$location.path('/foo');
and it will loads the /foo path - $routeProvider will then take care of loading the template associated with that path.
Reference: $location

Resources