Alexander Ponomarev
Alexander Ponomarev

Reputation: 105

Why data from parent directive doesn't pass to child directive

I have pretty simple code

<body ng-app="app">
<outer>
    <inner param="vm.test" param2="vm.test2"></inner>
</outer>
</body

my directives and controllers looks like

    function outerCtrl() {
        this.test = 'First test';
        this.test2 = 'Second Test';
    }

    function innerCtrl() {}

    angular
        .module('app', [])
        .controller('OuterCtrl', outerCtrl)
        .directive('outer', function() {
            return {
                // scope: {},
                restrict: 'E',
                transclude: true,
                template: "<div>I'm the outer part <br/> <ng-transclude></ng-transclude>",
                controller: "OuterCtrl as vm",
                bindToController: true
            }
        })
        .controller('InnerCtrl', innerCtrl)
        .directive('inner', function() {
            return {
                scope: {},
                require: '^^outer',
                restrict: 'E',
                template: "I'm the inner part - {{vm.param}} and {{vm.param2}}",
                controller: "InnerCtrl as vm",
                bindToController: {
                    param: '=',
                    param2: '='
                }
            }
        });

And actually it works. But it's get broken when I define the isolated scope for outer directive (if I just uncomment scope definition for outer directive) How to fix this?

https://codepen.io/ponomarev_aleksandr/pen/ypQymP

Upvotes: 1

Views: 56

Answers (1)

AlbertK
AlbertK

Reputation: 13187

Why it is not working:

In your working example you don't pass data from the parent directive to the child. Since your outer directive has scope:false by default, it doesn't create an own scope, hence it is in the outer scope (in a root scope in this case) and OuterCtrl is in the root scope as vm property. So actually you pass data from the root scope to inner directive.

When you uncomment scope: {} outer directive creates its own isolated scope with vm property and you cannot use it in outer scope (root scope). You can use it only inside outer directive (in its template).

How to fix it with isolated scope:

1) Probably you need to place your inner directive into outer directive template. Then you will be able to pass data from the outer directive to the inner directive.

2) If the first approach is not possible work with the outer scope (root scope here) from outer directive:

2.1) via $scope.$parent. But in most cases this is not the best approach because this code becomes fragile.

2.2) introduce additional variables in the root scope and bind them two-directional to the outer directive's scope variable and then pass them to inner directive

Upvotes: 1

Related Questions