[angular] 생성자와 ngOnInit의 차이점

Angular는 ngOnInit기본적으로 수명주기 후크 를 제공합니다 .

ngOnInit우리가 이미 있다면 왜 사용해야 constructor합니까?



답변

이것은 Constructor클래스가 인스턴스화 될 때 실행되는 클래스의 기본 메소드이며 클래스 및 해당 서브 클래스에서 필드의 적절한 초기화를 보장합니다. Angular 또는 DI (Dependency Injector)는 생성자 매개 변수를 분석하고 호출하여 새 인스턴스를 작성할 때 생성자 매개 변수 new MyClass()유형과 일치하는 제공자를 찾고이를 분석하여 생성자 에게 전달합니다.

new MyClass(someArg);

ngOnInit Angular가 구성 요소 만들기를 완료했음을 나타 내기 위해 Angular에서 호출 한 수명주기 후크입니다.

OnInit이를 사용하려면 다음과 같이 가져와야 합니다 (실제로 구현하는 OnInit것이 필수는 아니지만 모범 사례로 간주 됨).

import { Component, OnInit } from '@angular/core';

그런 다음 메소드를 사용하려면 다음 OnInit과 같이 클래스를 구현해야합니다.

export class App implements OnInit {
  constructor() {
     // Called first time before the ngOnInit()
  }

  ngOnInit() {
     // Called after the constructor and called  after the first ngOnChanges() 
  }
}

지시문의 데이터 바인딩 된 속성이 초기화 된 후 사용자 정의 초기화 로직을 실행하도록이 인터페이스를 구현하십시오. ngOnInit는 지시문의 데이터 바인딩 속성을 처음 확인한 직후와 자식을 확인하기 전에 호출됩니다. 지시문이 인스턴스화 될 때 한 번만 호출됩니다.

대부분 우리 ngOnInit는 모든 초기화 / 선언에 사용하며 생성자에서 작동하는 것을 피합니다. 생성자는 클래스 멤버를 초기화하는 데만 사용해야하지만 실제 “작업”을 수행해서는 안됩니다.

따라서 constructor()의존성 주입을 설정 하는 데 많이 사용해야 합니다. ngOnInit ()은 “시작”하기에 더 좋은 곳입니다-구성 요소의 바인딩이 해결되는 위치 / 시간입니다.

자세한 내용은 여기를 참조하십시오.


답변

기사 Angular에서 Constructor와 ngOnInit의 근본적인 차이점은 여러 관점과의 차이점을 탐구합니다. 이 답변은 구성 요소 초기화 프로세스와 관련된 가장 중요한 차이점 설명을 제공하며 사용법도 다릅니다.

각도 부트 스트랩 프로세스는 두 가지 주요 단계로 구성됩니다.

  • 구성 요소 트리 구성
  • 변화 감지 실행

Angular가 컴포넌트 트리를 생성 할 때 컴포넌트의 생성자가 호출됩니다. 모든 수명주기 후크는 실행중인 변경 감지의 일부로 호출됩니다.

Angular가 컴포넌트 트리를 구성 할 때 루트 모듈 인젝터가 이미 구성되어 있으므로 모든 글로벌 종속성을 주입 할 수 있습니다. 또한 Angular가 자식 구성 요소 클래스를 인스턴스화 할 때 부모 구성 요소 인젝터도 이미 설정되어 있으므로 부모 구성 요소 자체를 포함하여 부모 구성 요소에 정의 된 공급자를 주입 할 수 있습니다. 구성 요소 생성자는 인젝터 컨텍스트에서 호출되는 유일한 방법이므로 종속성을 얻는 유일한 장소 인 종속성이 필요한 경우.

Angular가 변경 감지를 시작하면 컴포넌트 트리가 구성되고 트리의 모든 컴포넌트에 대한 생성자가 호출되었습니다. 또한 모든 구성 요소의 템플릿 노드가 DOM에 추가됩니다. @Input생성자에서 사용할 수있는 특성을 가지고 기대할 수 있도록 통신 메커니즘은 변화 검출시 처리됩니다. 이후에 사용할 수 있습니다 ngOnInit.

간단한 예를 보자. 다음 템플릿이 있다고 가정하십시오.

<my-app>
   <child-comp [i]='prop'>

따라서 Angular는 응용 프로그램을 부트 스트랩하기 시작합니다. 내가 말했듯이 먼저 각 구성 요소에 대한 클래스를 만듭니다. 그래서 MyAppComponent생성자를 호출합니다 . 또한 my-app구성 요소의 호스트 요소 인 DOM 노드를 작성합니다 . 그런 다음 child-comp호출 ChildComponent생성자에 대한 호스트 요소를 작성합니다 . 이 단계에서는 실제로 i입력 바인딩 및 수명주기 후크와 관련이 없습니다 . 따라서이 프로세스가 끝나면 Angular는 다음과 같은 컴포넌트 뷰 트리로 끝납니다.

MyAppView
  - MyApp component instance
  - my-app host element data
       ChildCompnentView
         - ChildComponent component instance
         - child-comp host element data  

그런 다음에 만 변경 감지를 실행 하고 MyAppComponent 클래스 에서 my-app및 호출 ngOnInit에 대한 바인딩을 업데이트합니다 . 그런 다음 ChildComponent 클래스 의 child-comp및 호출 ngOnInit에 대한 바인딩을 업데이트합니다 .

생성자 또는 ngOnInit사용 가능한 항목에 따라 초기화 논리를 수행 할 수 있습니다. 예를 들어 다음은 @ViewChild 쿼리를 평가하기 전에 ViewContainerRef를 얻는 방법 입니다. 생성자에서 어떤 유형의 초기화 논리를 수행해야하는지 보여줍니다.

다음은 주제를 더 잘 이해하는 데 도움이되는 기사입니다.


답변

가장 좋은 예는 서비스를 사용하는 것이라고 생각합니다. 구성 요소가 ‘활성화’되면 서버에서 데이터를 가져오고 싶다고 가정 해 봅시다. 서버에서 가져온 후 데이터에 추가 작업을 수행하고 싶다고 가정 해 보겠습니다. 오류가 발생하여 다르게 기록하려고합니다.

생성자보다 ngOnInit을 사용하면 정말 쉽습니다. 또한 응용 프로그램에 추가해야하는 콜백 레이어 수를 제한합니다.

예를 들어 :

export class Users implements OnInit{

    user_list: Array<any>;

    constructor(private _userService: UserService){
    };

    ngOnInit(){
        this.getUsers();
    };

    getUsers(){
        this._userService.getUsersFromService().subscribe(users =>  this.user_list = users);
    };


}

내 생성자로 _userService를 호출하고 user_list를 채울 수 있지만 추가 작업을 원할 수도 있습니다. 모든 것이 대문자인지 확인하는 것처럼 데이터가 어떻게 전달되는지 완전히 확신하지 못합니다.

따라서 ngOnInit을 사용하기가 훨씬 쉽습니다.

export class Users implements OnInit{

    user_list: Array<any>;

    constructor(private _userService: UserService){
    };

    ngOnInit(){
        this.getUsers();
    };

    getUsers(){
        this._userService.getUsersFromService().subscribe(users =>  this.user_list = users);
        this.user_list.toUpperCase();
    };


}

훨씬 쉽게 볼 수 있으므로 다른 곳에서 파지 않고 초기화 할 때 구성 요소 내에서 함수를 호출하면됩니다. 실제로 나중에 더 쉽게 읽고 사용할 수 있도록 사용할 수있는 또 다른 도구 일뿐입니다. 또한 생성자 내에 함수 호출을 넣는 것이 실제로 나쁜 습관이라는 것을 알았습니다!


답변

OK, 우선 ngOnInit의 일부입니다 각도 수명주기 동안 constructor의 일부입니다 ES6 의 주요 차이는 바로 여기에서 시작하므로, 자바 스크립트 클래스! …

Angular의 수명주기를 보여주는 아래 차트를보십시오.

ngOnInit 및 생성자

Angular2 +에서는 우리를 위해 사용 constructor하는 DI(Dependency Injection)반면 Angular 1에서는 String 메서드를 호출하고 어떤 종속성이 주입되었는지 확인하여 발생했습니다.

위의 다이어그램에서 볼 수 있듯이 ngOnInit생성자가 준비된 ngOnChnages후 발생하고 구성 요소가 준비된 후에 해고됩니다. 모든 초기화는이 단계에서 수행 될 수 있습니다. 간단한 샘플이 서비스를 주입하고 초기화 할 때 초기화됩니다.

당신이 우리의 사용을 얼마나보고,보고에 대한 확인, 나는 또한 샘플 코드를 공유 ngOnInit하고 constructor아래 코드 :

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';


@Component({
 selector: 'my-app',
 template: `<h1>App is running!</h1>
  <my-app-main [data]=data></<my-app-main>`,
  styles: ['h1 { font-weight: normal; }']
})
class ExampleComponent implements OnInit {
  constructor(private router: Router) {} //Dependency injection in the constructor

  // ngOnInit, get called after Component initialised! 
  ngOnInit() {
    console.log('Component initialised!');
  }
}


답변

첫 번째 (생성자)는 클래스 인스턴스화와 관련이 있으며 Angular2와 관련이 없습니다. 모든 클래스에서 생성자를 사용할 수 있음을 의미합니다. 새로 만든 인스턴스에 대한 초기화 처리를 넣을 수 있습니다.

두 번째는 Angular2 구성 요소의 수명주기 후크에 해당합니다.

공식 앵귤러 웹 사이트에서 인용 :

  • ngOnChanges 입력 또는 출력 바인딩 값이 변경되면 호출됩니다.
  • ngOnInit 첫 번째 이후에 호출 ngOnChanges

따라서 ngOnInit초기화 처리가 구성 요소의 바인딩 (예 :으로 정의 된 구성 요소 매개 변수 @Input) 에 의존 하는 경우 사용해야 합니다 . 그렇지 않으면 생성자가 충분합니다 …


답변

위의 설명에서 생략 된 중요한 사항 하나만 추가하고 언제 사용 해야하는지 설명하겠습니다 ngOnInit.

ViewChildren , ContentChildren 또는 ElementRef 등을 통해 구성 요소의 DOM을 조작 하는 경우 생성자 단계에서 기본 요소를 사용할 수 없습니다.

그러나 ngOnInit컴포넌트가 생성되고 확인 ( ngOnChanges)이 호출되면이 시점에서 DOM에 액세스 할 수 있습니다.

export class App implements OnInit, AfterViewInit, AfterContentInit {
  @Input() myInput: string;
  @ViewChild() myTemplate: TemplateRef<any>;
  @ContentChild(ChildComponent) myComponent: ChildComponent;

  constructor(private elementRef: ElementRef) {
     // this.elementRef.nativeElement is undefined here
     // this.myInput is undefined here
     // this.myTemplate is undefined here
     // this.myComponent is undefine here
  }

  ngOnInit() {
     // this.elementRef.nativeElement can be used from here on
     // value of this.myInput is passed from parent scope
     // this.myTemplate and this.myComponent are still undefined
  }
  ngAfterContentInit() {
     // this.myComponent now gets projected in and can be accessed
     // this.myTemplate is still undefined
  }

  ngAfterViewInit() {
     // this.myTemplate can be used now as well
  }
}


답변

짧고 간단한 대답은

Constructor: constructorA는 default method(실행 deafult 의해 성분이 구성되는 경우). an instance클래스 를 만들면 해당 시간도 constructor(default method)호출됩니다. 즉, 컴포넌트 constructed or/and an instance is created constructor(default method)가 호출 될 때 호출되고 관련 코드가 작성됩니다. 기본적으로 일반적으로 구성 요소가 추가 용도로 구성되는 경우 Angular2와 같은 것을 주입하는 데 services사용됩니다.

OnInit: ngOnInit는 구성 constructor(default method)요소가 초기화 될 때 먼저 실행되는 구성 요소의 수명주기 후크입니다 .

따라서 생성자가 먼저 호출되고 생성자 메서드 후에 나중에 Oninit가 호출됩니다.

boot.ts

import {Cmomponent, OnInit} from 'angular2/core';
import {ExternalService} from '../externalService';

export class app implements OnInit{
   constructor(myService:ExternalService)
   {
           this.myService=myService;
   }

   ngOnInit(){
     // this.myService.someMethod() 
   }
}

리소스 : LifeCycle hook

두 가지 구현을 보여주는 이 작은 데모 를 확인할 수 있습니다 .