How to find out which directives were applied to an element? - javascript

Is there a way to find out, for any given element, which AngularJS directives were applied on it/its attributes?
In a large web application, I am looking at an HTML element that has an additional attribute that I suspect might invoke a directive (the attribute name is obviously specific to our application). Or it might simply be dead code.
It looks something like this:
<button ctl-remember-special data-ng-click="handleAction()"></button>
(ctl-remember-special being the possible directive in this example)
I cannot seem to find a directive of the appropriate name in our project, but I am not entirely sure because some of the identifiers in our application are assembled at runtime. (To provide an impression of the dimensions, I am seeing more than 6000 directive definitions in our code.)

Related

Polymer - Load different components dynamically

I'm a Polymer novice, but I guess what the answer will be...
Recently I came across with this issue: I got to loop through a collection of elements (using dom-repeat) and display its contents. But every element has a unique display and bindings, making it almost impossible to display each element dynamically. The ideal scenario would be to load a different component for each display type, but it looks like there is no easy way to achieve this.
Some options I have been thinking of were the following:
Using dom-if but it would add crap to my resulting HTML.
Is there a dom-switch? If it were something like that and didn't leave empty template tags (as it would do with dom-if) it would be nice.
It's possible to load a component dynamically? Using something like this: <[[item.type]] item-configuration=[[item.configuration]]></[[item.type]]>
Any other ideas? I would really appreciate any ideas or solutions or at least a workaround for my issue.
TL;DR; you can't
Polymer (and Web Components in general I guess) are best when used in a declarative way. Out-of-the-box your best solution is dynamically creating elements and adding to DOM or messy use of dom-if.
(potential) OPTION 1
I guess you could fairly easily implement a dom-switch element to work like
<template-switch switch="[[some.value]]">
<template-case case="10">
<element-one></element-one>
</template-case>
<template-case case="20">
<element-two></element-two>
</template>
<template-default>
<element-one></element-one>
</template-default>
</dom-switch>
I wrote this off the top of my head. There are multiple ways to implement such an element. A crucial decision is whether to use <template> internally or not. In this plunk I've implemented such element without templates but simply using content distribution.
OPTION 2
There is also Polymer.Templatizer.
Faced with a similar issue of choosing element to render dynamically I created this Plunk as a proof of concept.
As you see, you extend the <template> element with custom rules, which match against a model. You then bind the matched template's nodes with the model using Polymer.Templatizer.
Thanks to Templatizer, you don't have to pollute your actual element with conditionals and still get full binding functionality.
I'm working on a more feature-complete solution. If you're interested I could move it to a separate repository and publish.

Is it better convention to make angularjs directives "attributes" or "elements"

When making angular directives, it seems there are a set directives that could just as reasonably be defined as an HTML element, or an attribute. I am trying to figure out what the community convention (if any) is around which one to pick, and why.
So for example, an attribute centric view may be:
<div list-container>
<div list-filter/>
<div list="listOptions"/>
</div>
and the same in a element style view:
<list-container>
<list-filter />
<list controller="listOptions" />
</list-container>
My personal preference is for the second one (seems easier to read, dont have to worry about spans vs divs, etc), but most of the examples and libraries i've seen seem prefer the attribute approach (makes for valid html?)
If you want to support IE8 or below, forget elements. Attributes or class names is the way to go.
Otherwise, I think it largely depends on the type of directive:
If the directive is meant to be used as a component, i.e. substantial functionality, has it's own template etc, I would go for an element. Examples are tab controls, accordions, calendar etc.
If the directive is just about adding a small behavior to either a built-in element (input, select etc) or a custom directive of the first kind, I would make it an attribute.

Difference between the directives and static DOM elements in AngularJS

I have already read the
Compilation process, and directive matching
on AngularJS Doc.
but I really didn't understand the directives.
Example:
I have static html:
<div class="test test2" cid="549" sid="a5e3c4f8a9">text-text-text</div>
when I do it manually, I know it will only created and called one time at browser's parse time.
but what happens when I create a directive with the same dom element ?
<x my-directive>text-text-text</x>
is this the same effect?
I am asking such a newbie question, because I am using over 200 elements on my html page.
If I change them to single directive: for sure it will be much more easier to manage them.
and its no problem if its only slow at browser's compile time but what happend in run time?
and I am sorry, if the qustion is not pro enought. I am just new to Stackoverflow.
Thank You
Daniel
If I understand you correctly, you want to know how AngularJS creates a directive and how many times your directive methods are called.
When you create a directive (with module.directive('myDirective', ...)), you are really just creating a definition. Every time you use that directive (like <div my-directive>), AngularJS will run through the process described in the guide: that is, it will compile and link each use. It has to be this way because the directive doesn't exist in isolation; it exists not only in the $scope in which it was called, but also it can make use of element attributes and transcluded contents. The definition occurs once, but each instance is compiled and linked.
Once the directive is created, it's technically done; if you don't set up any $watch or $observe or event bindings, your "directive" is now just whatever's in the DOM at the end of your link function - there's no more computation. In other words, what happens after compilation and linking is entirely up to you.
So back to your example: if you use 200 of the same directive on the page, the directive will be defined once, but all 200 will be compiled and linked separately. But I'm not really sure what you're implying by asking. What's the question behind your question?

Are there javascript template engines that support something like recursion?

The most obvious example I can think of is for outputting nested comments. Let's say you have a tree of comments and you want to output it as nested html (let's say lists inside lists or divs inside divs) using your template.
The "comment" block/function/tag/helper/whatever would have to be able to call itself somehow for the comment's children.
Are there template engines that would support that sort of thing inside one template file?
I am aware that you can just pre-compute the "indent" or "depth-level" of each comment and send them to the template as one flat list in the correct order, but let's just say I don't want that. And let's say I don't want to stitch snippets together in code / outside the template - I want the whole page self contained in one template or theme file.
Update: I want to generate nested html. I want the comments to be nested, not appear nested. I know how to indent things with CSS. :) Whether it is done in the browser or on the server is irrelevant because the point is I want the template to be self-contained in one file.
As in:
var html = render(template, {comments: aTreeOfNestedComments});
(see? that could be node.js, a brower plugin, some "jQuery" as some people like to call javascript these days...) It looks like jade can do this using mixins. Any tag-based templating engines that can do something similar?
Template engines can solve generic, run-off-the-mill problems. While nesting templates seems like a common use case, I haven't encountered many template engines who can do that.
Since the market didn't offer a good solution, I'm building my applications from JavaScript objects that know how to render themselves. I never use templates; every block gets a reference to the DOM (like the parent element to which is should attach itself) or the renderers return the child container and the parent element can add that in a suitable place.
This allows me to use the full power of JS without the limitations of template engines.
[EDIT] Here is a workaround: If you need a recursive element, add a span (if the recursive element should be inline) or div (if it's a block element). Give it the class recursiveTemplate and a data attribute data-template-name="..."
Run the template with your standard template engine. Afterwards, use jQuery or the like to find all elements with the class recursiveTemplate and replace them yourself.
Distal templates has an example here of a nested tree:
http://code.google.com/p/distal/wiki/UseCaseExamples#Building_a_nested_tree
as #TJHeuvel said, you can use the server side script to produce the desired otput, this would be the best way to do what you require. However if you must use JavaScript, I would advise jQuery this will also allow you to product the desired result.
for example:
$("ul li").css("margin-left", "10px");

A convention for indicating whether an HTML element is referenced from JS code

This is a follow-up question for In jQuery is it a bad idea to use name=X for all selectors?
I am using Backbone and decided that I wanted a way to differentiate between HTML elements that were bound and those that were not.
So I would write (in HAML):
.container
.title(name='title')
.separator
As you can see it's clear that the dynamic element is title.
The reason for this was so I could mess around with the style and rename classes without worrying about breaking the app. It also means in the template I can tell what the dynamic elements are without needing to go back and forth with the Backbone View.
My question now is, without using the [name] selector, does anyone have a code convention to keep track of which HTML elements are referenced from JS.
I have considering:
Using a common prefix on class names (e.g. class=bind-title)
Using some sort of custom HTML element (
Thanks!
FYI: I'm using CoffeeScript, Backbone and haml_coffee templates.
Updated jsperf to test all suggestions:
http://jsperf.com/class-or-name-attr-lookup/3
I would consider using a class to indicate that it is dynamic.
I'm not sure if you are aware of this but you can have multiple classes on one element. Like so:
.container
.dynamic.title(name='title')
.separator
This works in traditional HAML but I have not tried it with haml-coffee. If it doesn't work, you might have to specify the class like .title{:class => "dynamic"}(name='title').
I prefer this over a prefix on the class name because it's more semantically meaningful, which is how HTML should be used.
I am using data-view attribute on elements being set when rendering my Views.
This helps me to then show a tooltip in a browser window when I hover over View(s).

Categories

Resources