Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 dependency injection vs @ViewChild

Tags:

angular

I am wondering what the difference between using dependency injection component and @ViewChild. The both ways I can use the parent attributes methods. So, when I should one and other?

Dependency Injection

import { Component, OnInit } from '@angular/core';
import { CompB } from './compb/compb.component';

@Component({
    moduleId: module.id,
    selector: 'app-test',
    templateUrl: 'compA.html'
})
export class CompAComponent implements OnInit {

    constructor(private _compB: CompB) {
    }
    ngOnInit() {
       this._compB.getName();
    }

}

@Component({
    moduleId: module.id,
    selector: 'app-test',
    templateUrl: 'compB.html'
})
export class CompBComponent {
    getName() {
       return 'Hello World';
    }
}

@ViewChild

import { Component, OnInit } from '@angular/core';
import { CompB } from './compb/compb.component';

@Component({
    moduleId: module.id,
    selector: 'app-test',
    templateUrl: 'compA.html'
})
export class CompAComponent implements OnInit {
    @ViewChild(CompB) compB: CompB
    ngOnInit() {
       this._compB.getName();
    }

}

@Component({
    moduleId: module.id,
    selector: 'app-test',
    templateUrl: 'compB.html'
})
export class CompBComponent {
    getName() {
       return 'Hello World';
    }
}

As you can see, the both methods I have access to the getName() in compBComponent.

like image 826
Tiago Matos Avatar asked Oct 31 '25 13:10

Tiago Matos


2 Answers

I think the names should be obvious enough...

@ViewChild gives you the reference to an actual view child created inside your view. The lifetime of the child totally depends on the lifetime of current component.

Injectable component returns you the object of the specified class (that appears to be a component) which was created by Angular's DI module. The lifetime of this object will be managed by Angular's DI rule (which providers array you put this in).

In your example, there's no difference, because a Component can be an injectable object, and your getName function more likely belongs to a service, not component. Component is designed to be a visible module that displays info to users or takes info back from them. Let's take another example, where you have an input in your compBComponent that allows user to input the new name, and getName will be out of context without user's input. In this case, DI compBComponent will become irrelevant.

Plunker to play with (Updated to Final): http://plnkr.co/edit/dn9CiGUrswW2FQgLPWwW

like image 107
Harry Ninh Avatar answered Nov 03 '25 03:11

Harry Ninh


with @viewChild u have to do nothing and it will give you current instance of child at each point of time.

With Dependency Injection...we have to explicitly add providers for child in parent and this will provide instance of child on first time load only..no change detection happens.

---Parent component----

import { ChildComponent } from './../child/child.component';
import { AfterViewInit, Component, OnInit, ViewChild } from '@angular/core';
@Component({
  selector: 'app-parent',
  templateUrl: './parent.component.html',
  styleUrls: ['./parent.component.css'],
  //providers: [ChildComponent]
})
export class ParentComponent implements OnInit, AfterViewInit {
  @ViewChild(ChildComponent) _child: ChildComponent;
  constructor(
    //private _child: ChildComponent
  ) { }
  ngOnInit() {
  }
  ngAfterViewInit() {
    console.log(this._child.getName());
  }
  getChildName() {
    console.log(this._child.getName());
  }
}
<app-child></app-child>
<button (click)="getChildName()">Get Child</button>

---child component---

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
  public name = 'sama';
  constructor() { }
  ngOnInit() {
  }
  getName() {
    return this.name;
  }
  setName(name: string) {
    this.name = name;
  }
}
<input type="text" [(ngModel)]="name">  
like image 42
Samadhan Avatar answered Nov 03 '25 05:11

Samadhan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!