Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi-Level Component Callbacks in Angular 1.5

I am coming from a React / Redux mindset where data-manipulation functions as well as data are passed from parent to child to grandchild etc. Components themselves do not modify data, rather they pass their intentions back up the component tree.

I am trying to replicate this with components in Angular 1.5. Consider the following:

app.js:

const appController = ($scope, data) => {
  $scope.doSomething = () => console.log('Foooooo!');
};

app.html:

<div>
  <node
    do-something="doSomething()"
  ></node>
</div>

node.js:

app.component('node', {
  // ...
  bindings: {
    doSomething: '&',
  },
});

node.html:

<div>
  <leaf
    do-something="$ctrl.doSomething()"
  ></leaf>
</div>

leaf.js:

app.component('leaf', {
  // ...
  bindings: {
    doSomething: '&',
  },
});

leaf.html:

<div ng-click="$ctrl.doSomething()"></div>

This works. When the div in leaf is clicked 'Foooooo!' is logged to the console. However, if I change the ngClick callback to pass in something in scope for leaf (or even just a literal such as 'foo') and change doSomething in app.js to take an argument that argument is undefined. My guess is that I have to somehow pass the data along in node, but I don't know how. Is there a way to pass arguments along intermediary components without having to write wrapper functions in scope? I've tried using arguments but that doesn't work -- is there some Angular way to accomplish what I want?

EDIT:

Plunkr: https://plnkr.co/edit/7L4Kd3rhJXoGlrHzecHf?p=preview

like image 870
knpwrs Avatar asked May 09 '16 17:05

knpwrs


1 Answers

EDIT: This may or may not actually work...

It would appear as though when you call a function that was provided with the & operator that you are not calling the function directly, but rather calling a function which uses its argument as a sort of context for the expression. The following works:

app.js:

const appController = ($scope, data) => {
  $scope.doSomething = value => console.log(value);
};

app.html:

<div>
  <node
    do-something="doSomething(value)"
  ></node>
</div>

node.js:

app.component('node', {
  // ...
  bindings: {
    doSomething: '&',
  },
});

node.html:

<div>
  <leaf
    do-something="$ctrl.doSomething({ value: value })"
  ></leaf>
</div>

leaf.js:

app.component('leaf', {
  // ...
  bindings: {
    doSomething: '&',
  },
});

leaf.html:

<div ng-click="$ctrl.doSomething({ value: someVar })"></div>
like image 112
knpwrs Avatar answered Oct 23 '22 05:10

knpwrs