R
R
Roman Chasovitin2018-09-07 07:55:47
JavaScript
Roman Chasovitin, 2018-09-07 07:55:47

How to call a component method from another component?

Good morning everyone! There was a small question. I have a component that has a button that, when clicked, should trigger an event in another component. The nesting of components is very large ( 1>1>1>1>1>comp1 and 1>2>2>2>2>comp2). Decided to do it through Subject. When I click, I call a method in the service that makes my Subject next(). also in the service there is a method that returns this Subject. So, everything works and subject successfully does next() and when subscribing to it in the service itself, everything works fine. But the problem arises, how to subscribe to the Subject in the second component? If at onInit or onChange, then it does not work.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Anton Shvets, 2018-09-07
@Xuxicheta

component 1

constructor (
  private myService: MyService,
) {}
onMyButton() {
  this.myService.triggerOnMyButton();
}

component 2
constructor (
  private myService: MyService,
) {}
ngOnInit() {
  this.myService.trigger$.subscribe(() => this.myMethod());
}

service
private _trigger = new Subject<void>();
get trigger$() {
  return this._trigger.asObservable();
}
public triggerOnMyButton() {
  this._trigger.next();
}

and, this is not reflected here, do not forget to unsubscribe

P
Pantene742, 2018-09-07
@Pantene742

Subject or Via Redux if using ngrx. Even if the components are loaded through the container. then instead of the outlet component, you can make a reference
In the component:

component: any;

@ViewChild('mainContent', { read: ViewContainerRef })
  mainContent: ViewContainerRef;

load the component into the container as through the outlet in the component code:
in the component variable we enter the data of the component:
this.component = this.mainContent.createComponent(this.cF.resolveComponentFactory(Название компонента из переменной как для компонент оутлета тип -> ComponentRef);

Further ..... this.component.instance.MethodFromComponent() And all properties and methods loaded into the container will be available to us. Also, methods can be async and you need to call them
await this.component.instance.MethodFromComponent()
But we needed this method for the reason that each component loaded into the container had methods with the same name. In the parent of the insole back - forward. And we, as it were, in the current child, understood the user wants to go back or go further, if the call returned a fall, we did not let it go back or forward did not switch to a new component. In the children there were onGoBack and onGoNext and if the form on goNext turns out to be not valid, the error output and the return of false and the parent knows that it is not necessary to switch to the next one.
Another option from stackoverflow.
When the loading of the component through the departure to the container is not used , and the method is inserted into the parent by hardcode .
@Component({
  selector: 'child-cmp',
  template: '<p>child</p>'
})
class ChildCmp {
  doSomething() {}
}
@Component({
  selector: 'some-cmp',
  template: '<child-cmp #child></child-cmp>',
  directives: [ChildCmp]
})
class SomeCmp {
  @ViewChild('child') child:ChildCmp;
  ngAfterViewInit() {
    // child is set
    this.child.doSomething();
  }
}

From the child to the parent, it is best to knock through the output. And it is unrealistic for a child to know the methods of the parent (as above) since childs are for reuse. (A crutch in all cases) And the fact that Vish is also a crutch. For maximum readability of a Redux or Subject project. Also where it is logical Input Output.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question