How to conditionally apply a template via custom Angular directives?

后端 未结 6 783
攒了一身酷
攒了一身酷 2020-12-29 02:37

DEMO

Consider the following directive:

angular.module(\'MyApp\').directive(\'maybeLink\', function() {
  return {
    replace: true,
    s         


        
相关标签:
6条回答
  • 2020-12-29 02:48

    I think this is the cleanest way to inject a dynamic template based on a scope property

    angular.module('app')
    .directive('dynamic-template', function () {
      return {
        template:'<ng-include src="template"/>',
        restrict: 'E',
        link: function postLink(scope) {
          scope.template = 'views/dynamic-'+scope.type+'.html';
        }
      };
    })
    
    0 讨论(0)
  • 2020-12-29 02:48

    You can use ng-if for the same

    Below is the working example

    Working Demo

    Directive Code:

    angular.module('MyApp').directive('maybeLink', function() {
      return {
        replace: true,
        scope: {
          maybeLink: '=',
          maybeLinkText: '='
        },
        template: '<span>' + 
                  '  <span ng-if="!maybeLink.link" ng-bind-html="text"></span>' +
                  '  <a ng-if="maybeLink.link" href="#" ng-bind-html="text"></a>' +
                  '</span>',
        controller: function($scope) {
          $scope.text = $scope.maybeLinkText.replace(/\n/g, '<br>');
        }
      }; 
    });
    
    0 讨论(0)
  • 2020-12-29 02:50

    The following is a solution that provides dynamic updates. Usage:

    <a rewrite-as-span="true"></a>

    <a rewrite-as-span="false"></a>

    <a rewrite-as-span="yourFn()"></a>

    etc.

    app.directive('rewriteAsSpan', function($compile){
      return {
        restrict: 'A',
        template: '<span />',
        replace: true,
    
        // we transclude the element because when it gets replaced with the span
        // we want all the properties from the original element
        transclude: 'element',
    
        compile: function(tElement, tAttrs){
    
          return {
            post: function(scope, element, attrs, controller, transclude){
              var rewrittenEl, originalEl;
    
              transclude(scope, function(clone){
                originalEl = clone;
              });
    
    
              scope.$watch(attrs.rewriteAsSpan, function(value){
                if (value === undefined || value === true){
                  if (!rewrittenEl){
                    // lazy compile and cache the rewritten element
                    transclude(scope, function(clone){
                      rewrittenEl = tElement;
                      rewrittenEl.html(clone.html());
                      // remove this directive because the $compile would get infinite
                      rewrittenEl.removeAttr('rewrite-as-span');
                      $compile(rewrittenEl)(scope);
                    });
    
                  }
    
                  element.replaceWith(rewrittenEl);
                  element = rewrittenEl;
    
                } else {
                  element.replaceWith(originalEl);
                  element = originalEl;
                }
              });
    
            }
          };
        }
      };
    });
    

    Code and specs as a gist

    0 讨论(0)
  • 2020-12-29 03:08

    I came up with the following version at the end:

    angular.module('MyApp').directive('maybeLink', function($compile) {
      return {
        scope: {
          maybeLink: '=',
          maybeLinkText: '='
        },
        link: function(scope, element, attrs) {
          scope.$watch('maybeLinkText', function(newText) {
            scope.text = newText.replace(/\n/g, '<br>');
          });
    
          scope.$watch('maybeLink', function() {
            var newElement;
    
            if (scope.maybeLink) {
              newElement = $compile('<a href="#" ng-bind-html="text"></a>')(scope);
            } else {
              newElement = $compile('<span ng-bind-html="text"></span>')(scope);
            }
    
            element.replaceWith(newElement); // Replace the DOM
            element = newElement;            // Replace the 'element' reference
          });
        }
      };
    });
    
    0 讨论(0)
  • 2020-12-29 03:10

    You might be able to use a template function. According to the docs:

    You can specify template as a string representing the template or as a function which takes two arguments tElement and tAttrs (described in the compile function api below) and returns a string value representing the template.


    function resolveTemplate(tElement, tAttrs) {
    
    }
    
    angular.module('MyApp').directive('maybeLink', function() {
      return {
        //...
        template: resolveTemplate,
        //...
      }; 
    });
    
    0 讨论(0)
  • 2020-12-29 03:11

    I would use ng-switch.

    something like

     template: '<span ng-switch on="maybeLink">' + 
              '  <span ng-switch-when="http://www.yahoo.com" ng-bind-html="text"></span>' +
              '  <a ng-switch-when="http://google.com" href="#" ng-bind-html="text"></a>' +
              '</span>',
    

    or

     template: '<span ng-switch on="maybeLink">' + 
              '  <span ng-switch-when={{maybeLink.length == 0}} ng-bind-html="text"></span>' +
              '  <a ng-switch-when={{maybeLink.length > 0}} href="#" ng-bind-html="text"></a>' +
              '</span>',
    

    So this is direction

    Plunker

    0 讨论(0)
提交回复
热议问题