简体   繁体   中英

Why can't I use data-* as a directive's attribute name in AngularJS?

On the t his plunker you can notice a strange behavior with the attribute name's pattern data-* in a directive.

The call :

<body ng-app="apptest" ng-controller="Controller">
  Test of data named attribute :
  <br/>
  <directivetest data-test="vartest" test="vartest" another-test="vartest"></directivetest>
</body>

of the directive :

angular.module('apptest', [])
  .controller('Controller', ['$scope',
    function($scope) {
      $scope.vartest = "This is a test";
    }
  ])
  .directive('directivetest', function() {
    return {
      restrict: 'E',
      scope: {
        dataTest: '=',
        test: '=',
        anotherTest: '='
      },
      templateUrl: "directive.html"
    }
  });

will take all the attributes of directivetest into account but data-test and therefore display :

 Test of data named attribute : Attribute with data-* name : Attribute with regular name : This is a test Attribute with an other regular name : This is a test 

I am wondering why this happens (I wasted 4 hours before I figured out that it was the issue).

It seems to be impossible to name a directive data-* , why is that?

I read something about it here http://www.w3schools.com/tags/att_global_data.asp , is it why my attribute is undefined? It is simply not read by the browser?

The data- prefixed forms of directive names allow HTML validators to work because custom data attributes in HTML5 follow that form. AngularJS directive names are normalized as follows to support custom data attributes:

The normalization process is as follows:

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

Angular automatically normalizes the attributes. Things like data-test="..." , x-test="..." , and test="..." are considered to be the same. You should choose one way of writing your custom attributes and stick with it; not mixing and matching.

This is because Angular strip x- and data- from the front of the element/attributes. Thus in your case you have two attributes named test and one overwrites the other. I've forked your plunker as an example: Plunker

<directivetest data-foo="vartest" test="vartest" another-test="vartest"></directivetest>

scope: {
    foo: '=',
    test: '=',
    anotherTest: '='
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM