3

I am new to angular 2, so please excuse me if this question sounds trivial to you. I am creating a feature module in angular 2 and I will export all the components from this module. Main module can import it and add this module in import list. By doing so, all the "template" in main module can access feature module's component.

But what I want is: in one of the my main module's component, I want to refer feature module's component as ViewChild.

Mistalis
  • 17,793
  • 13
  • 73
  • 97
Pragmatic
  • 3,093
  • 4
  • 33
  • 62

5 Answers5

2

You need to import the component class with a TypeScript import like

import {MyComponent} from './my.component'

then you can use it in @ViewChild()

@ViewChild(MyComponent) myComponent:MyComponent;
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • Is this right to access internal file from a different module? Had it been in same module, this seems fine. If I go this way, why do I need to put it in feature module's import list. – Pragmatic Nov 02 '16 at 12:56
  • You might be right. But you are not using module feature at all. You are just bypassing the module. As I wrote before, would that work if component is not in feature module's export list? I guess, it would. – Pragmatic Nov 02 '16 at 13:03
  • 1
    These two things are not related. You need the `@NgModule()`s, `declarations: []`, `imports: []`, and `exports: []` for using components, directives, and pipes in templates of modules and for lazy loading with the router, but for `@ViewChild()` you just need the TypeScript import to make it clear what class you are referring to with `MyComponent`. This later part is not related to `@NgModule()` in any way. – Günter Zöchbauer Nov 02 '16 at 13:10
  • 1
    That sounds logical. Here is a text from angular site: "Importing BrowserModule made all of its public components, directives and pipes visible to the component templates in AppModule". Imported objects are only available for Templates. – Pragmatic Nov 02 '16 at 13:42
2

@ViewChild can be used with a local id (prefixed by #), and you don't have to import the defining class. Of course you can't then type the variable comp as MyComponent.

In the template:

<my-component #myComponent></my-component>

In the javascript:

@ViewChild('myComponent') comp: any;

(Note the quote marks)

Alternatively
You can re-export a component from a feature module

// my.module.ts

import {MyComponent} from './my.component'

@NgModule({
  ...
})
export class MyModule {}
export {MyComponent} 

Then in the consuming component (where you want to use @ViewChild)

import {MyComponent} from '../common/my.module'

Now Typescript has a working reference to the class, but only the feature module needs to be referenced, not the individual component(s).

Richard Matsen
  • 20,671
  • 3
  • 43
  • 77
0

Please consider creating a shared module (feature) which will provide that component to both module. Please see official documents for structuring the app with shared module

Arpit Agarwal
  • 3,993
  • 24
  • 30
0

ViewChild is a decorator that you use to query your template to get the child that was imported from your feature module. if you template is :

<div>
  <child></child>
</div>

by using @ViewChild you can get your child component reference

almog
  • 798
  • 1
  • 7
  • 18
0

You can use service and EventEmitter for this.

import { Injectable, EventEmitter } from '@angular/core';


    @Injectable()
    export class MyService  {

        resultIdFound: EventEmitter<any> = new EventEmitter<any>();

        resultFound(resultId: string) {
            this.resultIdFound.emit(resultId)
        }
    }

Source component is:

import { Component, EventEmitter } from '@angular/core';
import { MyService } from './myservice';

    @Component({
    //..
    })
    export class SourceComponent implements OnInit {
        constructor(
            private router: Router,
            private myService: MyService) { }

        onResultFound(resultId: string): void {

            this.myService.roomSeached(this.selectedRoom.id)
        }
    }

and Target component is:

import { Component, EventEmitter,NgModule } from '@angular/core';
import { MyService } from './myService';

    @Component({
    //...
    })
    export class TargetComponent implements OnInit {
        constructor( 
            private myService: MyService
        ) {
           this.myService.resultIdFound.subscribe((result: any) => {
                 console.log(result)
            });

        }    
        //....    
    }
asdf_enel_hak
  • 7,474
  • 5
  • 42
  • 84
  • Thanks for your answer! But that is a work around to make communication possible among different component. Do you mean that a component from a module cannot access another component from different module using ViewChild? – Pragmatic Nov 02 '16 at 13:00