0

I have a directive, where I'm trying to dynamically load different partials depending on an object that is injected into directive

function countSummary() {
    var directive = {
        scope: {
            countData: '='
        },
        link: link,
        template: '<div ng-include=\'countData.countType === "expected" ? ' +                         '"/app/count/countsummary/countExpected.html" :' +
                   '"/app/count/countsummary/countBlind.html"\'>' +
                   '</div>'
    }
    return directive;

    function link(scope, element, attrs) { ... } 
}

I'm using grunt-html2js to convert all html files to be added to $templateCache. I have verified that the html file is in added to $templateCache, however when I load the page it is having difficulty finding only the .html files that are referenced in the template function.

Is this a timing issue of any sort? Is there a better way to use the template function?

Jon Harding
  • 4,928
  • 13
  • 51
  • 96
  • What happens if you remove the condition and add the template directly?, like this: ng-include="\'/app/count/countsummary/countExpected.html\'" Does the template loads? – Saulo Lozano Aug 14 '15 at 15:06
  • Conditional ng-include may not be the most clean approach to dynamic templates, but it is ok. Please, post the code with the module that defines the template to plunker. – Estus Flask Aug 14 '15 at 15:20
  • That was my first line of defense as well. Turns out that the templates are case sensitive and I just needed to fix my path countsummary > countSummary – Jon Harding Aug 14 '15 at 15:20
  • @estus http://stackoverflow.com/questions/31995874/angularjs-dynamically-load-templateurl-when-passing-object-into-attribute Here is how I go there, open to new solutions – Jon Harding Aug 14 '15 at 15:21

1 Answers1

1

ng-include argument needs to evaluate to URL. I'd do the following, which will be dynamic as the scope variable changes (using the ng-if directive will conditionally switch between views):

function countSummary() {
  var directive = {
    scope: {
      countData: '='
    },
    link: link,
    template: '<div ng-if="countData.countType === \'expected\'" ng-include="\'/app/count/countsummary/countExpected.html\'"></div>' +
    '<div ng-if="countData.countType !== \'expected\'" ng-include="\'/app/count/countsummary/countBlind.html\'"></div>'
  }
  return directive;

  function link(scope, element, attrs) { ... } 
}

An alternative way of doing this, which opens up a lot more options, is to compile in the link function:

<script type="text/ng-template" id="my_template_1">
  <div ng-if="countData.countType === 'expected'" ng-include="/app/count/countsummary/countExpected.html"></div>
  <div ng-if="countData.countType !== 'expected'" ng-include="/app/count/countsummary/countBlind.html"></div>
</script>

function link(scope, element, attrs) {

  var html = $templateCache.get('my_template_1');

  // parse HTML into DOM element
  var template = angular.element( html );

  // compile the template
  var linkFn = $compile(template);

  // link the compiled template with the scope
  var el = linkFn(scope);

  // append to DOM
  element.appendChild(el);
}
user12121234
  • 2,519
  • 2
  • 25
  • 27
  • This is a good solution, though it doesn't fit the question. I did ask a question prior to the $templateCache here if you want to add the answer there - http://stackoverflow.com/questions/31995874/angularjs-dynamically-load-templateurl-when-passing-object-into-attribute – Jon Harding Aug 14 '15 at 15:38