resulting HTML from $compile(custom-directive) doesn't bind {{values}}

2.5k views Asked by At

I want to dynamically add Angular custom Directives, but the directive resulting from $compile(directive) doesn't have the 2-ways binding.

Here's my simplified problem: I am using MapBox, and I want to use Directives for the the markers' popup to show, for example, the markers' title. MapBox wants HTML as a String to put inside the popup, so my idea was to pass a $compiled directive, something like $compile('<myDirective></myDirective>')($scope).html().

It replace the directive with its template, but {{values}} are not solved.

I have something like this to create the popup

map.featureLayer.on('layeradd', function(e) 
 {
  var marker = e.layer;
  var popupContent =  ctrl.createPopup(marker);
  // popupContent should be HTML as String
  marker.bindPopup(popupContent);
 });

ctrl.createPopup(marker) call a function of the controller, that does:

this.createPopup = function(marker)
{
 var popup = "<mapbox-marker-popup"
            +"      title = "+marker.feature.properties.title
            +"</mapbox-marker-popup>";
 // should return HTML as String
 return  ($compile(popup)($scope).html());
}

where mapbox-marker-popup is a directive specified as follow:

 /* ===== MARKER POPUP DIRECTIVE=========== */

 .directive('mapboxMarkerPopup', function() {
  return {
    restrict: 'E',
    template: [
                "<p>{{title}}</p>",
               ].join(""),
     scope:
        {
         title: '@'
        }
    }    
 })

Anyway... mapboxMarkerPopup is not working. title is shown as {{title}}

[UPDATE2 - {{title}} not solved]

Here's the JSFiddle

1

There are 1 answers

2
Pankaj Parkar On BEST ANSWER

You need to return the compile angular element instead of returning html of that element. Only returning the html will never carry the angular two way binding. By using compiled object you can keep your binding working.

Code

this.createPopup = function(marker) {
    var popup = "<mapbox-marker-popup" + 
      "title = '" + marker.feature.properties.title + "'" 
      + "</mapbox-marker-popup>";
    return ($compile(popup)($scope)[0]);
};

Working Fiddle

Update

$compile

Compiles an HTML string or DOM into a template and produces a template function, which can then be used to link scope and the template together.

Take a look at this link will give you more idea