7

That fiddle illustrates the issue http://jsfiddle.net/LAqeX/2/

I want to create a directive that wraps a part of the page and hides it. And i would like to use ng-if to remove unnecessary bindings. But some black magic happens.

This is my preferable directive code.

app.directive('withIf', function(){
    return {
        restrict: 'E',
        scope: {
            title: '@'
        },
        transclude: true,
        template: '<div>' +
        '<p ng-click="visible = !visible">{{title}}</p>' +
        '<div ng-if="visible" ng-transclude></div>'+
        '</div>',
        link: function(scope){
            scope.visible = false;
        }
    }
});

It is supposed to create two scopes:

  1. Directive isolate scope which has two variables - title and visible
  2. Transcluded scope which prototypically inherits from "regular" scope tree.

However, ng-if makes transclued scope somewhat detached from reality and trasncluded scope does not inherit from controller. Please, see the fiddle, it illustrates the issue very clear.

Any ideas what is happening there and how to solve it?

UPDATE

It seems i have figured out reasons why scope chain looks broken. The scope created by ng-if belongs to withIf directive isolate branch. So it never knows that controller's scope even exists. But the question remains the same - how to use ng-if in such case.

Eugene Kostrikov
  • 6,799
  • 6
  • 23
  • 25
  • Doesn't ng-if create isolate scope, more specifically? – frishi Feb 03 '15 at 16:43
  • It does, but i didn't expect it to break transcluded scope inheritance which should be literarily $parent. This is fixed in Angular 1.3 so just upgrade if you have similar issue. – Eugene Kostrikov Feb 03 '15 at 17:19
  • I did have a similar issue and resolved it using ng-show. Upgrading is not an option because of the size of the app I am working on. To that point, why is ng-if preferable to ng-show? I know that ng-show merely adds a class that hides stuff from the DOM and not remove it completely. Where is the advantage in ng-if? – frishi Feb 04 '15 at 19:52

2 Answers2

1

ng-if creates a child scope, use $parent to access variables from parent scope. But in your case I would consider using ng-show or ng-hide instead of ng-if (they don't create child scopes)

przno
  • 3,476
  • 4
  • 31
  • 45
  • 2
    At the moment i use ng-show and it works, but ng-show does not remove bindings from page. That's the reason why i want to use ng-if. – Eugene Kostrikov Mar 03 '14 at 09:55
1

This bug seems to be fixed in Angular 1.3 - https://github.com/angular/angular.js/pull/7499

VitalyB
  • 12,397
  • 9
  • 72
  • 94