2

I have following setup:

--Users
  --User Table Component
  --User Filtering State

When I go to Users, I can see component User Table Component. I am trying to access some object, that is in this component, from the state of User Filtering State.

Any ideas?

uksz
  • 18,239
  • 30
  • 94
  • 161

2 Answers2

2

approach 1: Template variables

One way is to use template variables. <some-component #someName> creates a someName variable with a reference to the SomeComponent component and this variable can be refered to in bindings:

@Component({
  selector: 'sibling1',
  template: `sibling1`)}
class Sibling1 {
  @Input() sib1Input;
  sib1Property:string = 'somevalue';
}

@Component({
  selector: 'sibling2',
  template: `sibling2`)}
class Sibling1 {
  @Input() sib2Input;
  sib2Property:string = 'somevalue';
}

@Component({
  selector: 'parent',
  directives: [Sibling1, Sibling2],
  template: `
<sibling1 #sib1 [sib1Input]="sib2.sib2Property"></sibling1>
<sibling2 #sib2 [sib2Input]="sib1.sib1Property"></sibling2>`)}
class Parent {
}

approach 2: Shared service

another way is to use shared services like demonstrated in
- Delegation: EventEmitter or Observable in Angular2

Below a simplified version (without observables). For how to use observables to get notified about changes, see the linked answer.

@Injectable() 
class SharedService {
  someValue:string;
}
@Component({
  selector: 'sibling1',
  template: `sibling1`)}
class Sibling1 {
  constructor(private sharedService:SharedServcie) {}

  clickHandler() {
    sharedService.someValue = 1;
  }
}

@Component({
  selector: 'sibling2',
  template: `sibling2
    <div>value from sibling1: {{sharedService.someValue}}</div>
`)}
class Sibling1 {
  constructor(private sharedService:SharedServcie) {}
}

Adding the SharedService to providers of Parent makes it shared among itself and it descendants (adding it to bootstrap(AppComponent, [SharedService]) would make it globally shared with the whole application)

@Component({
  selector: 'parent',
  directives: [Sibling1, Sibling2],
  providers: [SharedService], 
  template: `
<sibling1></sibling1>
<sibling2></sibling2>`)}
class Parent {
}
Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
1

You can't directly access properties on such components. If you want to communicate between components, you could leverage a shared service.

It could contain both data and observables to subscribe on to be notified when data are updated.

Here is a sample:

  • Service

    export class SharedService {
      list1Event: EventEmitter<any> = new EventEmitter();
    
      getLists() {
        return this.http.get(url).map(res => res.json())
          .subscribe(
            (data) => {
              this.list1Event.emit(data.list1);
            }
          );
      }
    }
    
  • Component

    @Component({
      selector: 'my-component1',
      template: `
        <ul>
         <li *ngFor="#item of list">{{item.name}}</li>
        </ul>
      `
    })
    export class MyComponent1 {
      constructor(private service:ListService) {
        this.service.list1Event.subscribe.(data => {
          this.list = data;
        });
      }
    }
    
  • bootstrap

    bootstrap(AppComponent, [ SharedService ]);
    

See this question for more details:

Community
  • 1
  • 1
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360