-1

TL;DR;
I want to write directive that replace tag innerHtml, into other tag attribute, and make it compiled. The expression is in ng-repeat (apparently this is important).
<ii>{{exp}}</ii> -> <i title="exp compiled!"></i>

Long story
I am having the next directive:

<span ng-repeat="name in names">
    <ii ng-class="{red: isRed}">Here comes HTML<br/> with {{name}} bla bla </ii>
</span>

The directive attached to the next Controller:

EZcountApp.controller('myCtr',function($scope){
    $scope.isRed = true;
    $scope.names= ['Alon','Moshe','Zvi'];
});

I want it to be compiled into the next output:

<i class="fa fa-question-circle" ng-class="{red: isRed}" title="
Here comes HTML<br/> with {{name}} bla bla
"></i>

And the final out put should be:

<span><i class="fa fa-question-circle red" title="Here comes HTML<br/> with Alon bla bla"></i></span>
<span><i class="fa fa-question-circle red" title="Here comes HTML<br/> with Moshe bla bla"></i></span>
<span><i class="fa fa-question-circle red" title="Here comes HTML<br/> with Zvi bla bla"></i></span>

I am using the next directive:

myApp.directive('ii',function(){
return {
        restrict: 'E',
        transclude: 'element',
        replace: true,
        scope: {},
        controller: function ($scope, $element, $attrs, $transclude) {
            // if there is no class of fa-XXXX
            // some login removed from here...
            $element.addClass('fa-question-circle');


        },
        template: "<i class='fa help-icon' data-toggle='tooltip' data-placement='top' ng-transclude></i>"
    };
});

The problem is that it's just not working, the text in title is not compiled.

Any help would be appreciated.

Attached here a plunnker of the buggy demo code, you may run

myApp = angular.module('myApp', []);
myApp.directive('ii', function() {
  return {
    restrict: 'E',
    transclude: true,
    replace: true,
    scope: {},
    controller: function($scope, $element, $attrs, $transclude) {
      // if there is no class of fa-XXXX
      // some logic removed from here...
      $element.addClass('fa-question-circle');
      //get data from the element and insert into title
      $scope.title = $element.html();
      //empty the element
      $element.empty();

    },
    template: "<i class='fa help-icon' data-toggle='tooltip' data-placement='top' title='{{title}}' ng-transclude></i>"
  };
});

myApp.controller('myCtr', function($scope) {
  $scope.isRed = true;
  $scope.names = ['Alon', 'Moshe', 'Zvi'];
});
.red {
  color: red
}
<div ng-app="myApp">

  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
  <div ng-controller="myCtr">
    actual result:
    <span ng-repeat="name in names">
    <ii ng-class="{red: isRed}" title="{{title}}"></ii><br/>
</span>
    results in console (<b>title attr is empty</b>):
    <pre>
    &lt;i class=&quot;fa help-icon ng-isolate-scope fa-question-circle red&quot; data-toggle=&quot;tooltip&quot; data-placement=&quot;top&quot; title=&quot;&quot; ng-transclude=&quot;&quot; ng-class=&quot;{red: isRed}&quot;&gt;&lt;/i&gt;
&lt;i class=&quot;fa help-icon ng-isolate-scope fa-question-circle red&quot; data-toggle=&quot;tooltip&quot; data-placement=&quot;top&quot; title=&quot;&quot; ng-transclude=&quot;&quot; ng-class=&quot;{red: isRed}&quot;&gt;&lt;/i&gt;
&lt;i class=&quot;fa help-icon ng-isolate-scope fa-question-circle red&quot; data-toggle=&quot;tooltip&quot; data-placement=&quot;top&quot; title=&quot;&quot; ng-transclude=&quot;&quot; ng-class=&quot;{red: isRed}&quot;&gt;&lt;/i&gt;
    </pre>
  </div>
</div>
desired results
<pre>
&lt;i title=&quot;Here comes HTML with Alon bla bla&quot; class="fa help-icon ng-isolate-scope fa-question-circle red" &gt;&lt;/i&gt;
&lt;i title=&quot;Here comes HTML with Moshe bla bla&quot;class="fa help-icon ng-isolate-scope fa-question-circle red" &gt;&lt;/i&gt;
&lt;i title=&quot;Here comes HTML with Zvi bla bla&quot; class="fa help-icon ng-isolate-scope fa-question-circle red" &gt;&lt;/i&gt;
</pre>
Wazime
  • 1,423
  • 1
  • 18
  • 26

2 Answers2

0

replace:true is Deprecated1

From the Docs:

replace ([DEPRECATED!], will be removed in next major release - i.e. v2.0)

specify what the template should replace. Defaults to false.

  • true - the template will replace the directive's element.
  • false - the template will replace the contents of the directive's element.

-- AngularJS Comprehensive Directive API

From GitHub:

Caitp-- It's deprecated because there are known, very silly problems with replace: true, a number of which can't really be fixed in a reasonable fashion. If you're careful and avoid these problems, then more power to you, but for the benefit of new users, it's easier to just tell them "this will give you a headache, don't do it".

-- AngularJS Issue #7636

Community
  • 1
  • 1
georgeawg
  • 48,608
  • 13
  • 72
  • 95
0

The directive ii uses isolate scope. To have the name variable from the parent scope visible on the directive scope, declare it in the isolate scope bindings.

scope: { name: '=" }
georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • Thanks, but scope is not the problem here. I can't make the innerHTML to become an attribute and the being compiled. Thanks for the try though... – Wazime May 30 '16 at 18:18