javascriptangularjsangularjs-directiveangularjs-scopeisolate-scope

Why is my angular directive not getting Parent controller scope inside isolated scope?


I've followed Angular docs precisely to get a directive working with an isolated scope containing a couple of vars from the parent Controller's scope object.

app.controller('MainCtrl', function($scope) {
    $scope.name = 'Parent Name';

    $scope.pokie = {
        whyIs: "thisUndefined?"
    };
});

app.directive('parseObject', function() {

    var preLink = function($scope, el, att, controller) {
        console.log('[link] :: ', $scope);
    };

    var postLink = function($scope, el, att, controller) {
        console.log('[PostLink] :: ', $scope);
        console.log('[$Parent] :: ', $scope.$parent.name);
    };

    return {

        restrict: 'E',
        scope: {
            myPokie: '=pokie',
            name: '=name'
        },
        template: [
          '<div>',
          '<h1>Directive does not get parent scope</h1>',
          '<h1>{{ myPokie }}</h1>',
          '<h2>{{ name }}</h2>',
          '</div>'
        ].join(''),

        compile: function() {
            return {
                pre: preLink,
                post: postLink
            }
        }
    }
});

http://plnkr.co/edit/FpQtt9?p=preview

Can anyone tell me what is wrong with my code? Why does the directive's Isolate scope return undefined values for 'myPokie' and 'name'?

I've seen other people saying you have to use $scope.watch for this.. but angular's directive docs don't say anything about that.. And I really don't want to use $scope.watch for something so trivial which should work out of the box.


Solution

  • As you declared isolated scope in your directive, that means you are going to provide those value to your directive using attribute.

     scope: {
         myPokie: '=pokie',
         name: '=name'
     }
    

    This means your directive scope will not be prototypically inherited from the parent scope. pokie attribute provide the value for myPokie & name attribute will provide value of name for your directive, = indicating a two way binding if your myPokie value change in directive, the same referencing value will change in the parent controller. The same is true for the name attribute.

    Your directive element markup should be:

    <parse-object pokie="pokie" name="name"></parse-object>
    

    Working Plunkr