How is this custom tag configured? - angularjs

I'm using this library https://github.com/tchatel/angular-treeRepeat
So to create a list of nodes this syntax is used :
<li frang-tree-repeat="node in treeData>
frang-tree-repeat is a custom tag and so it has to be configured somewhere within the library ?
Searching the src of https://github.com/tchatel/angular-treeRepeat I do not see any references to frang-tree-repeat so how is this tag configured or in other words how is frang-tree-repeat interpreted ?

Angular normalizes directive (both attribute and tag) names from kebab-case to camelCase. This is necessary since names of HTML tags and attributes are better written in kebab-case (because names are not case sensitive in HTML) while in Javascript kebab-case names would not be valid identifiers and could not be used for directives names (well, they could, but it would require additional wrapping into quotes).
That's the reason why you have to preform normalization from HTML notation to JS. Angular has $normalize service which is used for this. So it means, that if in HTML you have frang-tree-repeat it will be translated to frangTreeRepeat in Javascript.
In your case, your directive is found here: https://github.com/tchatel/angular-treeRepeat/blob/master/app/js/directives.js#L18

frang-tree-repeat is a custom directive which is defined in a module app.directives in angular-treeRepeat. As #dfsq pointed out, its implementation can be found here.
Note that it requires frangtreein its definition require: ^frangTree:
When a directive uses this option, $compile will throw an error unless the specified controller is found. The ^ prefix means that this directive searches for the controller on its parents (without the ^ prefix, the directive would look for the controller on just its own element).

Related

Angular Component Tag Name to div

I totally hate to add tag names based on component names in my apps. I hate to do this:
<hero-detail hero="ctrl.hero"></hero-detail>
Isn’t it possible to use normal div tags instead? Something like this?
<div id="hero-detail" data-hero="ctrl.hero"></div>
why isn’t that working?
You can technically restrict a component to an attribute as you do with directives since components are a special kind of directive. (I modified a random fiddle found on google)
EDIT: this does work on older 1.5 versions but not on newer ones. So read on...
But officially you cannot and you shouldn't do it anyway. If you choose a component architecture, you have to stick to the rules or things will get out of hands quickly.
Having components as html elements is clean and good practice. You should learn to like it.
why not, that is also possible.
basically in three ways we can specify the directives.
i.e Element, Attribute, Classname
but while create the directive you can specify
restriction : AE
or whaterver you need,
then you can use like this
<div id="hero-detail" hero-detail data-hero="ctrl.hero"></div>
for more have a deep look at the docs. directives
your answer is here https://docs.angularjs.org/guide/directive
They says:
Directive types $compile can match directives based on element names,
attributes, class names, as well as comments.
All of the Angular-provided directives match attribute name, tag name,
comments, or class name. The following demonstrates the various ways a
directive (myDir in this case) can be referenced from within a
template:
<my-dir></my-dir>
<span my-dir="exp"></span>
<!-- directive: my-dir exp -->
<span class="my-dir: exp;"></span>
Best Practice: Prefer using directives via tag name and attributes
over comment and class names. Doing so generally makes it easier to
determine what directives a given element matches.
Best Practice: Comment directives were commonly used in places where
the DOM API limits the ability to create directives that spanned
multiple elements (e.g. inside elements). AngularJS 1.2
introduces ng-repeat-start and ng-repeat-end as a better solution to
this problem. Developers are encouraged to use this over custom
comment directives when possible.

Angularjs v1 : Is it possible to create a data-custom-directive atrribute?

All is in the question :
I understood I have to declare the string with two custom letters than the uppercase word giving sense to the directive for example
djLoad
in the directive declaration which becomes
dj-load
in the view.
How about declaring
dataDjLoad
which would become
data-dj-load
in the view ?
The data prefix is stripped in the directive and attribute names by angular, so you should not use it. See "Normalization" section in the documentation.
The idea however is correct, directive declared as myDirectiveName (camelCase) should be used as my-directive-name or my:directive:name or my_directive_name in html.
If you still want to use the data prefix in your directive's name (e.g. dataDjLoad) - you should use it this way: <div data-data-dj-load></div>.
Here the EXAMPLE.

How can Angular use custom attributes without the data-* prefix, and everyone else says you shouldn't?

Everyone (W3C validator, stackoverflow posts, etc) says you should prefix custom attributes with data- (e.g. data-my-custom-attr="hey"). And you shouldn't use them like: my-custom-attr="hey".
Yet Angular encourages you to use things like ng-click etc without the data- prefix.
Is this just a question of best practise? Or is Angular being a bit of a maverick?..
Why do you say that angular encourages it? In fact if you check normalizations section for directives in angular documentation you will find a note that angular in parsing directives strips data- and x- prefixes so you don't have to access attributes and name directives like
.directive('dataMyCustomDirective', function(){})
but nothing tells you you can't or shouldn't use data- or x- prefix if you want your HTML to be validated against w3c validator, i personally use attributes without the prefix in development and use grunt task to add prefix for production
That's an interesting question. But I think it's more of a personal use. I use a custom prefix for all the attrs and declarations I create with the company prefix. e.g. mj-function -> MyJob-Function. Nothing stops me from doing this ang ignoreing the data- prefix.
This also helps me keeping the code more organized (if using third part libs). Because it's easy to locate. MJ is code built by myself. ng is Angular. Other is third.
Keep an eye!
What you have to avoid is to declare your attrs with the prefix ng if you are using AngularJS, because then you could have a conflict with AngularJS main directives. Like ngClick, ngChange, ngBlur, etc...
But nothing about use/not use data- prefix.

Angular $watch variable name with underscore or camel case doesn't get updated

When I $watch a variable with underscore or camel case in its name, the $watch doesn't trigger. If the variable name being $watch'ed does not contain any underscore or camel case, it works. I don't find anything talking about the variable name being $watch'ed in Angular documentations.
Here's the code that the $watch failed to trigger:
http://jsbin.com/potiferixu/1/edit?html,console,output
Here's the code that the $watch got triggered correctly:
http://jsbin.com/sulugukaka/2/edit?html,console,output
The only difference is the variable name.
In AngularJS, when you refer to variables with underscores inside a directive, you have to use the camelcase version.
Taken from the official documentation:
Angular normalizes an element's tag and attribute name to determine
which elements match which directives. We typically refer to
directives by their case-sensitive camelCase normalized name (e.g.
ngModel). However, since HTML is case-insensitive, we refer to
directives in the DOM by lower-case forms, typically using
dash-delimited attributes on DOM elements (e.g. ng-model).
So, you should use this in the scope:
scope: {
fieldWithUnderscore: '='
},
and this inside the $watch:
console.log(scope.fieldWithUnderscore);
And (as you pointed out) also to change this:
scope.$watch('fieldWithUnderscore'
Updated version: http://jsbin.com/zoqupizuvi/2/edit

in angular why not data-ng-* but ng-* [duplicate]

This question already has an answer here:
Do I still need to use data-ng with AngularJS or can I drop the data-?
(1 answer)
Closed 8 years ago.
I've come to know that data-ng-* is validation-friendly. But I've come across many places where I see snippets having ng-* over data-ng-*. Even the snippets in the angular official sites. Why is it so?
To embed custom non visible data we use data-. hence using data-ng- is suggested instead of ng-app To make it a valid html template.
Please refer : W3C
From the HTML 5.1 Editor's Draft,
3.2.5.9 Embedding custom non-visible data with the data-* attributes
A custom data attribute is an attribute in no namespace whose name
starts with the string "data-", has at least one character after the
hyphen, is
XML-compatible,
and contains no uppercase ASCII
letters.
And the official angularjs documentation:
What are Directives?
At a high level, directives are markers on a DOM element (such as an
attribute, element name, comment or CSS class) that tell AngularJS's
HTML compiler ($compile) to attach a specified behavior to that DOM element or even transform the DOM element and its children.
Angular comes with a set of these directives built-in, like ngBind,
ngModel, and ngClass. Much like you create controllers and
services, you can create your own directives for Angular to use. When
Angular bootstraps your
application, the HTML
compiler traverses the DOM
matching directives against the DOM elements.
And farther down the page:
Best Practice: Prefer using the dash-delimited format (e.g. ng-bind for ngBind). If you want to use an HTML validating tool,
you can instead use the data-prefixed version (e.g. data-ng-bind
for ngBind). The other forms shown above are accepted for legacy
reasons but we advise you to avoid them.
So directives of the form data-ng-* are only necessary if you want your HTML to validate. Otherwise, it's "deprecated". Use ng-* instead.

Resources