2

I'm struggling to call a parent controller function in a nested directive that recursively compiles itself. Clicking on the button in tree-item works one level deep, but after that the variables for doc and type are undefined.

This type of issue is trivially resolved with React, but I think new scopes are being created with every function pass, when really I just want to pass the callback reference from the parent.

I think this could be solved by emitting events, is this a bad / good idea?

Parent controller method:

displayDocument(doc, type) { /* */ }

Passed down to tree directive:

<tree display-document="vm.displayDocument(doc, type)"></tree>

Tree definition:

function Tree() {
  return {
    restrict: 'E',
    replace: true,
    templateUrl: 'components/ui/biospecimen/templates/tree.html',
    scope: {
      displayDocument: '&',
    }
  }
}

Passed to tree-item directive from tree.html:

<tree-item display-document="displayDocument(doc, type)"></tree-item>

TreeItem definition:

function TreeItem($compile) {
  return {
    restrict: 'E',
    replace: true,
    templateUrl: 'components/ui/biospecimen/templates/tree-item.html',
    scope: {
      displayDocument: '&',
    },
    link: (scope, el, attrs) => {
      el.append($compile([
        '<tree',        
          'data-ng-repeat="childType in [\'foo\', \'bar\']"',
          'display-document="displayDocument(doc, type)"',
        '></tree>'
      ].join(' '))(scope))
    }
  }
}

And then finally used inside tree-item:

<button data-ng-click="displayDocument({ doc: doc, type: type })">Click</button>    

1 Answer 1

1

Your almost there. Your problem is that when you invoke a function from a directive, you must pass it an object, just like you did when you pass the object from tree item to tree. Angular then invoke the function in the tree directive like so:

displayDocument(doc, type)

the problem is that this function is also inside a directive!, it must be invoked in the same way, like this:

displayDocument({ doc: doc, type: type })

So if the function in the tree directive must be invoked with one argument (that is the object { doc: doc, type: type }) then when you invoke it from the tree item, you must write it in the template like so:

<tree-item display-document="displayDocument(args)"></tree-item>

(or any other name instead of 'args') and invoke it like so:

<button data-ng-click="displayDocument({args: { doc: doc, type: type }})">Click</button>

I created a working js fiddle the resembles your situation

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.