Search code examples
angularjsangular-ui-routerui-sref

AngularJS: Correct way of doing directive with dynamic template and replace option on?


What is the easiest(and correct) way to have dynamic templates for directive and keep replace option (want to have all the attributes on my template).

I'm trying to create "link" directive that will be extension for ui-router/ui-sref : when the state is current state - we show just a text (not a link).

It's not a problem to do just dynamic templates via compile(or $compile service), but how could I keep replace option on, that passes all the directive attributes to the template.

So I would like to have

<ui-link ui-sref="dashboard.common" class="nav-alt__item">Dashboard</ui-link>

Like

<a ui-sref="dashboard.common" class="nav-alt__item">Dashboard</a>

in one case and

<span ui-sref="dashboard.common" class="nav-alt__item">Dashboard</span>

in another.

actually I don't need ui-sref for span, but it's not a big issue.

May be there is already existing extension solutions for ui-router.


Solution

  • You can have dynamic templates by supplying a function as template, but usually it is the wrong way because you don't have interpolated attribute values or anything else there that could be useful for making decisions.

    Nesting directives are what Angular is comfortable with.

    app.directive('uiLink', function () {
      return {
        scope: {
          uiSref: '@',
          current: '@?'
        },
        transclude: true,
        template: [
          '<a ng-if="!current" ui-sref="{{uiSref}}" ng-transclude></a>',
          '<span ng-if="current" ng-transclude></span>',
        ].join('')
      };
    });
    

    replace is not a option when there are multiple root elements in a template. So optional attributes (class, etc) should belong to ui-link and don't have to be translated to nested elements.