0

I can't get an ng-if to evaluate inside a directive. I was first calling a method that returned a boolean, but whatever the result the ng-if does not pick up the result, it always evaluates to false.

To try and pin point the issue I tried a simple inline expression (below) but even this always evaluates to false. When I remove the ng-if, the div shows. What am I doing wrong?

.directive('handsUpVideoOverlay', function() {
  return {
    restrict: 'E',
    replace: true,
    scope: false,
    template: '<div class="handsOffOverlay" ng-if="1>0">' +
    '</div>',
    link: function($scope) {

    }
  };
})

UPDATE

This code works perfectly as a standalone Jsfiddle. It looks like the problem is something to do with the fact I am adding this directive as a child of another directive. The parent directive is 3rd party and is manually transcluding it's children.

UPDATE

Ok I got this working. The problem was the parent directive was removing any child directive and then adding it back without compiling them. I had to take my own copy of the 3rd party parent directive and change this in the link function:

// Make transcluding work manually by putting the children back in there
      ng.element(element).append(oldChildren);

to this:

// Make transcluding work manually by putting the children back in there
  for(var i = 0; i < oldChildren.length; i++) {
      var template = oldChildren[i].outerHTML;
      var linkFn = $compile(template);
      var content = linkFn($scope);

      $element.append(content);
   }
Si-N
  • 1,495
  • 1
  • 13
  • 27

2 Answers2

1

UPD:

Since the question leads to directive in directive, and without $compile, angular won't know about the ng-if directive.So in the link function, build the elements to let template cimpiled.

OLD ANSWER(can ignore)

Your directive isn't end or you didn't post the entire code block. This work as expected.

var app = angular.module("app", []);
app.controller("myCtrl", function($scope) {
  $scope.test = 111;
});
app.directive('handsUpVideoOverlay', function() {
  return {
    restrict: 'E',
    replace: true,
    scope: false,
    template: `<div class="handsOffOverlay" ng-if="1>0">Test Directive</div>`,
    link: function($scope) {

    }
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="myCtrl">
  <hands-up-video-overlay></hands-up-video-overlay>
</div>
Pengyy
  • 37,383
  • 15
  • 83
  • 73
  • Sorry, missed the last line. Updated my question. I copied and pasted your code. Exactly the same problem. In my app the ng-if isn't being evaluated. When I remove the ng-if completely the div shows. I can put any expression in the ng-if: true, a method call, 1>0 etc it's never bringing back true. – Si-N Mar 17 '17 at 10:53
  • @Si-N did this code snippet works well on your broswer?(before copied to your local environment, just click the 'Run code snippet' button) – Pengyy Mar 17 '17 at 10:55
  • Yes your code, and my original code work perfectly in jsfiddle. It doesn't however work in the context of my app. I've just realised the problem seems to be the directive is a child of another directive that is doing manual transcluding of it's children. – Si-N Mar 17 '17 at 11:01
  • @Si-N ok, then you have to use $compile to let angular compile your template first or else angular's ng-if won't work. refer http://stackoverflow.com/questions/19224028/add-directives-from-directive-in-angularjs – Pengyy Mar 17 '17 at 11:05
  • ok thanks. I don't really understand the intricacies of how directives work under the hood yet so will take me a while to read up and make sense of that post. Sure that will resolve it though. – Si-N Mar 17 '17 at 11:17
  • @Si-N Sure, take your time. the $compile is an important part we should learn. – Pengyy Mar 17 '17 at 11:20
  • ok I think I get the basics of $compile now: Pass a template and a scope to angular saying hey remember this, link it up to this scope and please give me some markup back that I can use in my page at that you will from now on track. The problem is if this is the case, won't it be the parent directive that needs to compile my child directive? At the moment the parent just calls `ng.element($element).append(oldChildren);` to transclude my directive. I can't modify the parent as it is 3rd party. – Si-N Mar 17 '17 at 12:51
  • @Si-N interstring, how could the third-party directive get your own directive? whta's it? and the $compile is usually used for directive or $sce.trustAsHtml – Pengyy Mar 17 '17 at 12:54
  • Got it working with your help, thanks. Updated above. – Si-N Mar 17 '17 at 14:05
-1

Solved please check Jsfiddle link

Js code

  app.directive('handsUpVideoOverlay', function() {
    return {
      restrict: 'E',
      replace: true,
      scope: false,
      template: '<div class="handsOffOverlay" ng-if="1>0">lol' +
        '</div>',
      link: function($scope) {

      }
    };
  });

html

<hands-up-video-overlay></hands-up-video-overlay>

Hope this will help you

Jayant Patil
  • 1,537
  • 2
  • 11
  • 18
  • Thanks for quick response, but still not working for me. Only difference I can see in your code is the explicit annotate square brackets have been removed. The problem must be contextual. I remove the ng-if and the div shows. I copied and pasted your code exactly, same problem. – Si-N Mar 17 '17 at 10:49