5

Angular 1.5 component communication suggestions usually have output bindings to invoke methods on root controllers.

Let's say I have a root component, and two child components.

<root>
    <child-1></child-1>
    <child-2></child-2>
</root>

It'd like to react to a button click on component one by reading a value on component two and then doing something in the root.

For example, child-1 is a directive which wraps a drawing library that attaches a drawing to its DOM node and has a variable to control that drawing.

child-2 has a button. When it is clicked, data from the child-1 variable should be passed on to root which does something with it.

Specifically, child-1 wraps var graph2d = new vis.Graph2d(container, dataset, options);. Later on, I would like to retrieve some information from graph2d and pass it on to root to do something with it.

This boils down to: how can components react to events issued by other components? The inputs and outputs suggestions don't seem to cover that scenario.

ipavlic
  • 4,906
  • 10
  • 40
  • 77
  • Use two way binding and inject the data in both components: `child-1 <-> Controller <-> child-2` – trollr Apr 15 '16 at 11:51
  • @zeroflagL basically, I'm asking how can two disjoint components communicate with inputs and outputs in situations where one would need to react on event from another. – ipavlic Apr 15 '16 at 12:20
  • 1
    You can hold the state on a higher level component, or you can communicate between components by using $rootScope.$broadcast – Daniel Higueras Apr 15 '16 at 12:27
  • From what I understand the root component holds the relevant data (or at least has access to it) , the child-2 component fires an event to which the root component reacts. – a better oliver Apr 15 '16 at 12:55

1 Answers1

4

In angular 1.5 you can use require and/or property bindings (input/output) to communicate.

If you use the require property then your root component would publish an api and your child component would get a reference to the controller:

angular.module('app').component('child1', {
   bindings: {},
   require: {api: '^root'}, //your <root> component
   template: '',
   controller: controller
});

You can then use the methods of the root component in your child component:

$ctrl.api.addWatchedBook();

This is the root component controller function:

$ctrl.addWatchedBook = addWatchedBook;

function addWatchedBook(bookName){

  booksWatched.push(bookName);

}

Here is a complete architectual overview: Component Communications

kevinius
  • 4,232
  • 7
  • 48
  • 79
  • Is using `require` considered the best approach when a child component needs to respond to async requests? i.e. an edit form component that delegates its save method to a parent via an `&` binding, but needs to react to server error/success callbacks from the parent? – ken.dunnington Feb 08 '17 at 20:34
  • I dont feel this is a good approach since a child knows the parent component. It should be the inverse. A child should only emit events/functions through its bindings with `&` where a parent/container component will bind to it. – Danny Yassine Feb 07 '18 at 01:36