Compile directives from the Controller

4

I have a table that is rendered dynamically when passing an array of data to it. I have access to the data of each "row" as follows:

{
    "data": function (data, type, val, meta) {

        return "<div style=\"color:green;\">" + data.Valor + "</div>";
    }
}

I can put a html snippet there, as shown, but I'd like to put a progress bar, and since in the system I already have 'angular-ui' referenced, I wanted to use its directive, p>

<uib-progressbar class="progress-striped active" max="200" value="166" type="danger"><i>166 / 200</i></uib-progressbar>

or compile using $compiler of angularjs is not working.

How can I proceed?

    
asked by anonymous 29.07.2016 / 21:54

1 answer

2

Well, I'll leave an example with $compile same, take a look.

Example with JSON and ngRepeat:

var app = angular.module('app', ["ngAnimate","ui.bootstrap"]);

app.directive('compile', function ($compile) {
  return {
    restrict: 'A',
    link: function ($scope, $element, $attrs) {
      var html = $attrs.compile;
      $scope.$watch($attrs.compile, function(html) {
      	$element.html(html)
        $compile($element.contents())($scope);
      });
    }
  };
});

app.controller('compileProgressBar', function($scope) {
  $scope.createProgressBar = function(value, max, type){
    return '<uib-progressbar class="progress-striped active" max="'+ max + '" value="'+ value + '" type="'+type+'"><i>'+ value + ' / '+ max + '</i></uib-progressbar>'
  }
  $scope.empresas = [
  	{name: "Empresa 1", progress: 80, typeBar: "sucess"},
  	{name: "Empresa 2", progress: 20, typeBar: "danger"},
  	{name: "Empresa 3", progress: 50, typeBar: "warning"}
  ];
})
.progress { 
  height: 20px;
}
.progress i{ 
  line-height: 20px;
}
.progress-bar { 
  transition: width 1s ease-in-out; 
}
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-animate.js"></script>
    <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.0.1.js"></script>
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet">
 
<h2>Compile dynamic uiProgressBar in ngRepeat</h2>
<hr>
<div ng-app="app" ng-controller="compileProgressBar">
  <div ng-repeat="empresa in empresas" >
    {{empresa.name}} <div compile="createProgressBar(empresa.progress, 100, empresa.typeBar)"></div>
  </div>
</div>

Explaining ...

Javascript

I create the progressBar from a directive. So I first create the directive called compile . It will be applied to the element that will become the progressBar.

In the policy return object, the constraint to parameter ( restrict: 'A' ). So it can only be used as an attribute of a tag, as use in the examples, not <compile></compile> . What can be changed, but would also change the Controller.

In link , function inside the object to manipulate the DOM, I assign the arguments $scope , $element and $attrs .

Within the function, I use $scope.$watch , a function that "listening" for changes in something. In this case, it listens for changes in the compile directive and at each stage executes the callback .

In callback use .html() to modify the content of div which is the policy. The new content will have what will happen in the compile attribute, in the example, it is the html variable that receives $attrs.compile .

And lastly, I use% w / w of% itself, which takes as its argument the contents of the element ( $compile ). Passing $element.contents() to function as well.

Note: In your case, it is important to inject the dependency of $scope .

HTML

In this example I pass a function that returns a bar with values modified by its arguments, as in its example. The arguments of the function, in this case, are data coming from the JSON itself run in ngRepeat , in the case ["ui.bootstrap"] and empresa.progress . I know that uiProgressBar could come in the HTML itself, but as the intention is to show the use of empresa.typeBar , I leave it being returned as a string in the function.

Any problem with implementation, please let me know, so we can try to solve it.

I hope I have helped. Thanks.

    
09.08.2016 / 03:48