Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot use letter x to start html attribute in Angular

I noticed something very strange about Angular 1.5.6 components. I have a component called scale. I call it:

<scale x-scale="xScale"></scale>

And in my controller:

$scope.xScale = 'lin'.

And my component definition:

angular
    .module('myapp')
        .component('scale', {
            templateUrl: 'analyse/components/scales/scale.tpl.html',
            controller: function(){
                console.log('in controller and this is ', this);

            },
            bindings: {
              xScale: '='
            },
    });

The console log outputs undefined.

But if i change x-scale to r-scale in my template and xScale in the binding to rScale, suddenly it works. In fact it seems that if i replace the x with any other letter, it works. Why is this?

like image 370
Mark Avatar asked Nov 05 '16 23:11

Mark


1 Answers

It's in the documentation for directives

Normalization

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).

The normalization process is as follows:

  1. Strip x- and data- from the front of the element/attributes.
  2. Convert the :, -, or _ -delimited name to camelCase.

So Angular strips of x- from the front of any attribute name to normalize it, this is done because both regular data-attributes, starting with data-, and x-attributes, starting with x- is valid in HTML 5.

The HTML5 specification states that

Attribute names beginning with the two characters "x-" are reserved for user agent use and are guaranteed to never be formally added to the HTML language.

It also states that

For markup-level features that are intended for use with the HTML syntax, extensions should be limited to new attributes of the form "x-vendor-feature", where vendor is a short string that identifies the vendor responsible for the extension, and feature is the name of the feature.

The x- attributes aren't used very often, but as noted above they are reserved for browser vendors, and you shouldn't be using them, instead you should be using data-attributes, where incidentally, Angular will also remove the data- part for you, so these

<scale data-scale="scale"></scale>
<scale x-scale="scale"></scale>
<scale scale="scale"></scale>

are all the "same" when you do

$scope.scale = 'lin'.
like image 115
adeneo Avatar answered Oct 10 '22 15:10

adeneo