简体   繁体   中英

Dynamically change html element in Angular directive

Let's say have have a simple template for a directive like this:

<section class="card {{width}} recipe-list-card">
  <div class="card-top">
    <h3>{{headerText}}</h3>
  </div>
  <div class="card-bottom">
    <div ng-transclude></div>
  </div>
</section>

In some cases I'd like to use an h2 and in others and h3. Is there a good way to change the element with a directive?

Here's what I have in my directive:

module.exports = function(app) {

      app.directive('cardDirective', function() {
        return {
          restrict: 'AC',
          replace: true,
          transclude: true,
          templateUrl: '/templates/card_template.html',
          scope: {
            header: '=',
            headerText: '@',
            width: '@' //two columns, three columns, etc
          }
        }
      })
    }

I'd like to assign the header variable to h2, h3 etc. So far I've only been able to get escaped html (the actual tag rendered out like <h2> in the browser).

You can create a directive for your heading tag, like this:

angular.module('myApp')
    .directive('myHeading', myHeading);

function myHeading() {
    return {
        transclude: true,
        template: function(tElement, tAttrs) {
            var level = Number(tAttrs.level);
            if (level < 1 || level > 6) level = 1; // default
            return '<h' + level + '><ng-transclude></ng-transclude></h' + level + '>';
        }
    };
}

Then you could use it in your template like this:

<my-heading level="2">{{headerText}}</my-heading>

You can do it by following the code as follows

Change HTML as follows:

<section class="card {{width}} recipe-list-card">
  <div class="card-top">
    <h3 ng-show="h3">{{headerText}}</h3>
    <h2 ng-show="h2">{{headerText}}</h2>
  </div>
  <div ng-click="updateh2h3()">Check h2h3 changes</div>
  <div class="card-bottom">
    <div ng-transclude></div>
  </div>
</section>

And modify controller as follows: module.exports = function(app) {

  app.directive('cardDirective', function() {
    return {
      restrict: 'AC',
      replace: true,
      transclude: true,
      templateUrl: '/templates/card_template.html',
      scope: {
        header: '=',
        headerText: '@',
        width: '@' //two columns, three columns, etc
      },
      controller: function($scope) {
       $scope.h2 = false;
       $scope.h3 = true;
       $scope.updateh2h3 = function(){
        if($scope.h2){
         $scope.h2 = false;
         $scope.h3 = true;
        } else {
         $scope.h2 = true;
         $scope.h3 = false;
        }
       }
      }
    }
  })
}

You can simply add an attribute to the directive and use ng-switch to setup the header you need for your card. take a look this demo i've done.

<div class="card">
  <div class="card--Title" ng-switch on="headline">
      <h1 ng-switch-when="h1">{{::headerText}}</h1>
      <h2 ng-switch-when="h2">{{::headerText}}</h2>
      <span ng-switch-default>{{::headerText}}</span>
  </div>
</div>

http://embed.plnkr.co/simYTj/

I think you are looking at this issue the wrong way. Instead of switching tags around, you can just define two classes for h2 and h3, and then you can use ng-class to switch between. Dynamically compiling tags and manipulating dom for this is very expensive operation.

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