0

I have two components , component1 and component2

component1 contains following piece of code

export class CpOne{
   passedValue:number=null;

   setValue(x){
     this.passedValue = x;
   }
}

the component two contains following piece of code

import { CpOne }   from './component1'

export class CpTwo{
     constructor(private cp : CpOne){}
}

what I want to achieve , is somehow invoke setValue method of component1 in component2 , or basically send data from component2 to component1 and store them in passedValue variable.

Is such a thing possible in angular2 without using templates and passing value with it?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Darlyn
  • 4,715
  • 12
  • 40
  • 90
  • Have a look at https://angular.io/docs/ts/latest/cookbook/component-communication.html#!%23parent-to-child-local-var – Arpit Agarwal Jul 20 '16 at 12:12
  • @ArpitAgarwal what if i have multiple componentes imported? How do i specify i want to send data so specific one – Darlyn Jul 20 '16 at 12:22

3 Answers3

0

The data share does not work in that way. To share data between components you could use:

- @ViewChild/@ViewChildren
- Services
- @Input
- Observables
0

The global answer is to leverage a shared service and use it to communicate between components.

Most of the time, you need to define your shared service when bootstrapping your application:

bootstrap(AppComponent, [ SharedService ]);

and not defining it again within the providers attribute of your components. This way you will have a single instance of the service for the whole application.

You can implement the shared service like that:

export class SharedService {
  valueUpdated:Subject<any> = new Subject();

  updateData(data:any) {
    this.valueUpdated.next(data);
  }
}

To be notified, simply subscribe to the subject

constructor(private service:SharedService) {
  this.service.valueUpdated.subscribe(data => {
    // do something
  });
}

One component is a sub component of your AppComponent one, simply remove the providers attribute like this:

@Component({
  selector : "other",
  // providers : [SharedService], <----
  template : `
    I'm the other component. The shared data is: {{data}}
  `,
})
export class OtherComponent implements OnInit{
  (...)
}

This way they will shared the same instance of the service for both components. OtherComponent will use the one from the parent component (AppComponent).

This is because of the "hierarchical injectors" feature of Angular2. For more details, see this question:


By injecting the parent into the child, you need to be careful about cyclic dependency (use forwardRef - see https://angular.io/docs/ts/latest/api/core/index/forwardRef-function.html). But it's possible to have something like that:

@Component({
  template: `
    <div (click)="onClick()">Click</div>
  `,
  (...)
})
export class CpTwo{
  constructor(private cp : CpOne){}

  onClick() {
    this.cp.setValue({ value: 'some value' });
  }
}
Community
  • 1
  • 1
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
0

If you want to do that without using @intput/@output, I see two options:

Hope it helps.

Alexandre Junges
  • 988
  • 11
  • 13