Why does ngDirective `template` allow for correct `clientHeight` but `templateUrl` gives 0

35 Views Asked by At

TL/DR

plunker

// Foreign object is the right size
template: "<h1>{{name}}</h1>",

but

// Foreign object is size 0 why is that?
templateUrl: "dialog.html",

FULL

I have a plunker that demos what I am talking about. I am using a d3 library called dagreD3. It creates a foreign object in an svg using the following code...

function addHtmlLabel(root, node) {
  var fo = root
            .append("foreignObject")
            .attr("width", "100000");

  var div = fo
    .append("xhtml:div");

  var label = node.label;
  switch(typeof label) {
    case "function":
      div.insert(label);
      break;
    case "object":
      // Currently we assume this is a DOM object.
      div.insert(function() { return label; });
    break;
      default: div.html(label);
  }

  util.applyStyle(div, node.labelStyle);
  div.style("display", "inline-block");
  // Fix for firefox
  div.style("white-space", "nowrap");

  // IMPORTANT AREA
  var w, h;
  div
    .each(function() {
      w = this.clientWidth;
      h = this.clientHeight;
    });

  fo
    .attr("width", w)
    .attr("height", h);

  return fo;
}

Now the problem I am having is when I run the following code...

$scope.nodes = d3.range(20).map(function() {
  // IMPORTANT AREA
  var i = Math.floor(Math.random() * types.length),
      rand = types[i],
      nScope = $rootScope.$new();
  nScope.name = rand.label;
  var element = angular.element('<jg-item name="name"></jg-item>');
  $compile(element)(nScope);
  // END AREA
  return {
    radius: Math.random() * 36 + 10,
    label: element[0],
    labelType: "html",
    color: rand.color,
    typeIndex: i,
    radius: 50,
    shape: rand.shape ? rand.shape : "rect"
  };
});

Then if I have this in the directive...

// This works
template: "<h1>{{name}}</h1>"

Everything looks great but when I move the HTML out to an external file and import like this...

// This fails
templateUrl: "dialog.html",

Then the HTML is properly rendered but the foreign object has a width and height of 0.

What explains this (assuming it is with the digest cycle) and is there a way I can get around this limitation?

template: $templateCache.get("...")

?

1

There are 1 best solutions below

0
On

Apperently I was right this is hacky but seems to fix it...

$templateCache.put('test.html', '<h1>{{name}}</h1>');
...
template:$templateCache.get("test.html"),

Then it works. This solution is acceptable because I am already using HTML2JS to load these items into the cache.