Steve
Steve

Reputation: 41

Angular 2 Component communication confusion

i have recently started using angular 2 for a new project and haven some confusion on whats the best approach for the following.

I have a parent component (ROOT) which has 3 child components, A(a list of search result items in a table format), B(a google map) and C(a form with multiple inputs/select dropdowns ).

Component C (the refine form) should be the main driver in terms of the search criteria params used by an API endpoint located in a service i have injected into the ROOT parent component. The object returned (currently an observable from the http call) will be used to feed all 3 child components, render the list, map etc.

Now, what i really cant get my head around is:

1) How should i get the data out of the inputs/selects in the refine search component? Should i implement ouputs for each of the fields? or should the root parent used viewChild to somehow listen to changes to them?

2) Should i subscribe to the service observable in the parent, and then pass it to the list and map components?

Any help or advise would be greatly appreciated, theres a hell of a lot to learn im still trying to get my head around it all and not sure if im even approaching it in the right way :/

Upvotes: 4

Views: 848

Answers (2)

ovangle
ovangle

Reputation: 2031

The approach I use to designing collections of components like this is to have an informal notion of a smart and a dumb component and decide whether each component should be, based on the following criteria.

  1. A dumb component knows nothing of the world around it, if it has injected dependencies they are all stateless and synchronous. A dumb component never uses async except to pass DOM events to one of it's outputs.
  2. A smart component is aware of the world around it. It can have access stateful services and is responsible for the inputs and outputs of it's dumb children. Except for positioning dumb children within a container, a smart component should not be concerned with display or user input.

This then gives a neat way of defining how components communicate.

  • Two dumb components should never communicate with each other, unless one is a direct ancestor of the other. It should treat all children as if they were dumb components.
  • A smart component interacts with dumb children via their @Inputs and their @Outputs.
  • Two smart components communicate with each other (and the outside world) via injected services.

Based on your description of components 'A, B and C', here's how I'd categorise them

A: A list of search results.

Definitely a dumb component. It should have an @Input() for accepting the list of results, but the component has nothing to do with actually searching for the results, it just displays them.

B: A google map

Another dumb component, it just takes as @Input the options to display on the map and displays the map. It can have @Outputs based on user interaction with the map, but it is only concerned with displaying the data.

C: The form

Yep, you guessed right, another dumb component. It has an input which is the current model, and an output for when the user clicks the save button. It doesn't need to know about what the user has input, it just needs to provide the capability to enter the input (and validation for when the input is incorrect).

D: The root component

The smart component, in this simple example. It is not concerned with displaying the data, or accepting user input, it is responsible for coordinating interaction between the list, input and the map.

It should take data from the form, manipulate the api and display the results in the result container, making liberal use of the AsyncPipe from @angular/common so that none of the results, map or form have to know anything about each other.

Upvotes: 1

ranakrunal9
ranakrunal9

Reputation: 13558

I will suggest to use Input to pass data to child component upto first level [first level child only] and Output to emit event to imediate parent not for parent of parent.

There are different ways with which you can interact with your components. You can find all at component communication guide. But i will suggest you to go with the Parent and children communicate via a service so that you do not need to define more inputs and output on component.

You can check https://gist.github.com/ranakrunal9/7b26ccafbe29fcf4bdac4f9236e71e6a3 for Parent and children communicate via a service.

Upvotes: 0

Related Questions