Search code examples
methodsangularcomponentsviewchild

Angular2 access another components methods without loading its template with @ViewChild


I am trying to access a child components method with @ViewChild, and it works, but I am forced to load its template as well, which I don't want to do, because that also forces that child components OnInit, AfterViewInit and other system functions to run.

I want them to run only when I call this child component in a different scenario, but I want to access this childs custom methods on demand in AppComponent.

So how do I do it?

This is a plunker which depicts the problem: http://plnkr.co/edit/FT6GTJ8mmUnyFxJAPbGV

You can see that dashboards test() function is called, thats what I want, however, its ngOnInit function is also initialized, which I don't want.

template: <h1>AppComponent</h1><my-dashboard></my-dashboard>

I though it was pretty obvious to remove <my-dashboard></my-dashboard> from AppComponent template, to not load dashboards template, but then I get error that dashboard itself is not defined (you can see the error if u remove <my-dashboard></my-dashboard> and run the plunker again) even though I have included it through import statement.

What am I missing?

EDIT-----------------------------------------------------------------------------------------------------------------

So, in the end, you have to use a service to store reusable data/functions to work without a hick up.


Solution

  • Not entirely sure why you would want this, but you can try and use the Component as a provider. Although i fail to see how this can fall under the, "if it looks stupid, but it works, it ain't stupid", rule.

    import { Component, OnInit, AfterViewInit, ViewChild } from '@angular/core';
    import { DashboardComponent } from './dashboard.component';
    
    @Component({
        selector: 'my-app',
        template: `
          <h1>AppComponent</h1>
        `,
        providers: [DashboardComponent]
    })
    
    export class AppComponent implements OnInit {
    
        constructor(public dashboardComponent: DashboardComponent){}
    
        ngOnInit() {
            this.dashboardComponent.test();
        }
    
    }
    

    plnkr

    Another way I assume, could be to simply initiate a new class instance, this would result in something like this:

    import { Component, OnInit, AfterViewInit, ViewChild } from '@angular/core';
    import { DashboardComponent } from './dashboard.component';
    
    @Component({
        selector: 'my-app',
        template: `
          <h1>AppComponent</h1>
        `
    })
    
    export class AppComponent implements OnInit {
    
      public dashboardComponent: DashboardComponent = new DashboardComponent();
    
        constructor(){}
    
        ngOnInit() {
            this.dashboardComponent.test();
        }
    }
    

    plnkr

    But again I fail to see why you would want to do something like this. Apparently there is logic in your component which shouldn't be there