생성자와 ngOnInit의 차이점


1072

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

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


11
안녕하세요, Angular의 내부 작업 관점과의 차이점을 설명하는 내 대답 을 확인하십시오
Max Koretskyi


1
@MaximKoretskyi, 연결이 끊어졌습니다.
Yash Capoor

답변:


1108

이것은 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 ()은 "시작"하기에 더 좋은 곳입니다-구성 요소의 바인딩이 해결되는 위치 / 시간입니다.

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


62
정확히 말해서, 대부분의 클래스 기반 언어는 최종 필드 (TS가 있는지 알지 못함)와 같이 상당히 어려운 문제가 발생할 수있는 다른 클래스를 확장하는 클래스의 올바른 초기화 순서를 보장하는 구성자를 가지고 있습니다. Contstructor는 Angular2와 관련이 없으며 TypeScript 기능입니다. 수명주기 후크는 일부 초기화가 수행 된 후 또는 특정 상황에서 구성 요소가 작동하고 적절한 시간에 일부 작업을 수행 할 수있는 이벤트가 발생했을 때 Angular에 의해 호출됩니다.
Günter Zöchbauer 5

12
angular.io/docs/ts/latest/guide/server-communication.html 에는 다음과 같이 설명 하는 블록 인용문 이 있습니다. "구성자가 생성자가 단순하고 모든 실제 작업 (특히 원격 서버)는 별도의 방법으로 처리됩니다. " -이 경우 해당 메소드는 ngOnInit ()입니다.
yoonjesung

3
Angular가 구성 요소 만들기를 완료했음을 나타 내기 위해 Angular2에서 호출하는 수명주기 후크입니다. -정확히 아니에요. 바인딩이 초기화되었다는 신호입니다. 구성 요소가 이전에 작성되었습니다. 내 답변
Max Koretskyi

22
모든 "모범 사례"와 마찬가지로 생성자에서 "작업"을 수행하지 않아야하는 이유 도 설명하는 것이 좋습니다 . 각 팀의 리더에 의해이 문서는 조밀하지만 도움이 될 수 misko.hevery.com/code-reviewers-guide/...는 또한, 더 적은 중요성하는 OnInit를 구현하는 데 필요한 주술에 배치해야 더에 (이 쉽게 찾을 수 있습니다) 생성자에서 데이터 바인딩을 사용할 수 없다는 중요한 사실.
Reikim

2
tsconfig.json파일 모드에서 엄격 모드가 true 인 경우에는 like가 아닌 "strict": true의 클래스 멤버를 초기화해야합니다 . constructorngOnitFormGroup
Rohit Sharma

169

기사 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를 얻는 방법 입니다. 생성자에서 어떤 유형의 초기화 논리를 수행해야하는지 보여줍니다.

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


33
이것이 정답이어야합니다. 그것은 실제로 진언을 반복하고 진술하기보다는 WHY를 설명한다 the constructor should only be used to inject dependencies.
Stavm

1
@ yannick1976, 감사합니다! 참조 기사 확인
Max Koretskyi

@ flobacca, 당신은 질문을 다시 말해주십시오, 당신이 요구하는 것을 이해하기 어렵습니다
Max Koretskyi

내가 틀렸다면 정정 해주세요. 구성 요소 트리가 먼저 구성된 다음 감지 프로세스를 변경한다는 것을 알고 있습니다. 먼저 AppComponent 생성자를 호출하고 (종속성을 확인한 후) ChildComponent 생성자를 호출하고 (종속성과 함께) AppComponent에 대한 입력 바인딩을 작성한 다음 OnInit를 호출합니다. 그러나 내 우려는 두 구성 요소에 수명주기 후크를 추가하면 흐름은 AppComponentConstructor--> AppComponentOnInit — → ChildComponentConstructor — → ChildComponentOnInit입니다. ChildComponentConstructor 전에 userComponentOnInit가 호출되는 이유
user2485435

1
@MaxKoretskyiakaWizard 당신이 옳았습니다. 응용 프로그램 설정에서 실수를했습니다. 설명대로 작동합니다. angular-c7zjsx.stackblitz.io
user2485435

93

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

생성자보다 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();
    };


}

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


user_list를 Observable로 설정하면 예제를 단순화 할 수 있습니다. Angular2에는 비동기 파이프가 있으므로 아무런 문제가 없습니다.
DarkNeuron

@Morgan, 여기서 작은 것을 배우기 위해 왜 먼저 함수 getUsers를 만든 다음에 삽입 ngOnInit합니까? ngOnInit로 작성하는 코드가 아닌가? 사람들이 왜 이런 식으로하는지 궁금합니다. 원하는 경우 코드를 재사용 할 수 있습니까? 감사.
Alfa Bravo

31
아래 답변에서 볼 수 있듯이 생성자에있는 경우 아무런 차이가 없습니다. 이것은 목적에 대한 실제 답변이 아닙니다.
Jimmy Kane

8
이것이 어떻게 질문에 대답하는지 모르겠습니다. 왜 코드를 넣을 수 없었 constructor습니까?
CodyBugstein

1
@Morgan 왜 당신은 그냥 할 수 없습니다constructor(private _userService: UserService){ this.getUsers(); };
Ashley

82

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!');
  }
}

1
감사. 이것이 가장 좋은 대답이어야합니다.
Don Dilanga

58

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

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

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

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

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


49

위의 설명에서 생략 된 중요한 사항 하나만 추가하고 언제 사용 해야하는지 설명하겠습니다 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
  }
}

3
아니. 의 경우 @ViewChildren특히, 당신은 사용해야 할 ngAfterViewInit방법을. 여기를보십시오 : stackoverflow.com/questions/46314734/…
AsGoodAsItGets

1
감사합니다. @AsGoodAsItGets 지적합니다. 나는 이제 답을 개선했다
Miroslav Jonas

38

짧고 간단한 대답은

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

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


5
"생성자는 구성 요소가 초기화 될 때 실행되거나 호출되는 것"이라고 생각합니다. 오해의 소지가 있습니다. 생성자는 구성 요소가 아닌 클래스의 기능입니다. 클래스의 인스턴스는 생성자가 호출 되고 Angular가 초기화 한 후에 구성 요소 가된다고 말하고 싶습니다 .
Günter Zöchbauer 5

예, 지금 확인할 수있는 내용이 변경되었습니다.
micronyks 5

1
흠, IMHO는 여전히 똑같습니다. "구성자 (기본 메소드)는 컴포넌트가 생성 될 때 실행되거나 호출되는 것"입니다. 컴포넌트가 생성 될 때뿐만 아니라 서비스 또는 코드와 같은 코드 new MyClass()가 실행될 때 호출됩니다 . 생성자가 구성 요소, 클래스 및 이러한 클래스의 인스턴스 초기화에 관한 것이라고 오해의 소지가 있다고 생각합니다. 구성 요소는 그러한 클래스입니다. 그렇지 않으면 좋은 대답이라고 생각합니다.
Günter Zöchbauer

2
네 그럼요. 클래스의 객체를 만들 때 그 시간 constructor도 호출됩니다. 그러나이 답변은 angular2 컨텍스트로 작성되었습니다. 최상의 답변을 얻으려면 OOP 기본 사항을 알고 있어야합니다. 여전히 답변을 업데이트하겠습니다.
micronyks

@ GünterZöchbauer, 나는 그것이 구성 요소가 아닌 클래스의 기능 인 올바른 주장이라고 생각하지 않습니다 . 프로그래밍 언어 관점에서 그렇습니다. 그러나 라이프 사이클 후크없이 구성 요소를 성공적으로 사용할 수 있습니다. 그러나 DI가 필요한 경우 생성자가없는 구성 요소로는 작업 할 수 없습니다 .DI가 주입 가능한 유일한 장소이기 때문입니다. 보기 내 대답
최대 Koretskyi

20

다른 많은 언어와 마찬가지로 클래스 수준, 생성자 또는 메서드에서 변수를 초기화 할 수 있습니다. 특정 경우에 가장 적합한 것을 결정하는 것은 개발자의 몫입니다. 아래는 결정에 관한 모범 사례 목록입니다.

클래스 레벨 변수

일반적으로 나머지 구성 요소에 사용될 모든 변수를 여기에 선언합니다. 값이 다른 것에 의존하지 않으면 초기화하거나 const 키워드를 사용하여 상수가 변경되지 않으면 상수를 만들 수 있습니다.

export class TestClass{
    let varA: string = "hello";
}

건설자

일반적으로 생성자에서 아무것도하지 않고 주입 될 클래스에 사용하는 것이 가장 좋습니다. 대부분의 경우 생성자는 다음과 같아야합니다.

   constructor(private http: Http, private customService: CustomService) {}

이렇게하면 클래스 수준 변수가 자동으로 생성되므로 customService.myMethod()수동으로 수행하지 않고도 액세스 할 수 있습니다.

NgOnInit

NgOnit는 Angular 2 프레임 워크에서 제공하는 라이프 사이클 후크입니다. OnInit사용하려면 구성 요소를 구현해야 합니다. 이 수명주기 후크는 생성자가 호출되고 모든 변수가 초기화 된 후에 호출됩니다. 대부분의 초기화가 여기에 있어야합니다. Angular가 구성 요소를 올바르게 초기화했는지 확실하게 알 수 OnInit있으며 구성 요소가 제대로로드되지 않은 경우 필요한 논리를 수행하는 것과 비교할 수 있습니다.

다음은 호출 순서를 자세히 설명하는 이미지입니다.

여기에 이미지 설명을 입력하십시오

https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html

TLDR

Angular 2 프레임 워크를 사용 중이고 특정 라이프 사이클 이벤트와 상호 작용해야하는 경우 문제점을 피하기 위해 프레임 워크가 제공하는 메소드를 사용하십시오.


19

이것을 테스트하기 위해 NativeScript Tutorial 에서 빌린이 코드를 작성했습니다 .

user.ts

export class User {
    email: string;
    password: string;
    lastLogin: Date;

    constructor(msg:string) {        
        this.email = "";
        this.password = "";
        this.lastLogin = new Date();
        console.log("*** User class constructor " + msg + " ***");
    }

    Login() {
    }
}

login.component.ts

import {Component} from "@angular/core";
import {User} from "./../../shared/user/user"

@Component({
  selector: "login-component",
  templateUrl: "pages/login/login.html",
  styleUrls: ["pages/login/login-common.css", "pages/login/login.css"]
})
export class LoginComponent {

  user: User = new User("property");  // ONE
  isLoggingIn:boolean;

  constructor() {    
    this.user = new User("constructor");   // TWO
    console.log("*** Login Component Constructor ***");
  }

  ngOnInit() {
    this.user = new User("ngOnInit");   // THREE
    this.user.Login();
    this.isLoggingIn = true;
    console.log("*** Login Component ngOnInit ***");
  }

  submit() {
    alert("You’re using: " + this.user.email + " " + this.user.lastLogin);
  }

  toggleDisplay() {
    this.isLoggingIn = !this.isLoggingIn;
  }

}

콘솔 출력

JS: *** User class constructor property ***  
JS: *** User class constructor constructor ***  
JS: *** Login Component Constructor ***  
JS: *** User class constructor ngOnInit ***  
JS: *** Login Component ngOnInit ***  

18

생성자의 주요 차이점은하고 ngOnInitngOnInit이다 라이프 사이클 후크 와 생성자 후 실행됩니다. 구성 요소 보간 된 템플릿 및 입력 초기 값은 생성자에서 사용할 수 없지만에서 사용할 수 있습니다 ngOnInit.

실제 차이점은 ngOnInit코드 구성 방식에 어떤 영향을 미치는지입니다. 대부분의 초기화 코드로 이동할 수 있습니다 ngOnInit- 이 경쟁 조건을 생성하지 않는만큼 .

생성자 반 패턴

대량의 초기화 코드는 생성자 메서드를 확장, 읽기 및 테스트하기 어렵게 만듭니다.

초기화 로직을 클래스 생성자와 분리하는 일반적인 방법은 init다음 과 같은 다른 메소드로 이동하는 것입니다 .

class Some {
  constructor() {
    this.init();
  }

  init() {...}
}

ngOnInit 구성 요소 및 지시문에서이 목적을 수행 할 수 있습니다.

constructor(
  public foo: Foo,
  /* verbose list of dependencies */
) {
  // time-sensitive initialization code
  this.bar = foo.getBar();
}

ngOnInit() {
  // rest of initialization code
}

의존성 주입

Angular에서 클래스 생성자의 주요 역할은 종속성 주입입니다. 생성자는 TypeScript의 DI 주석에도 사용됩니다. 거의 모든 종속성은 클래스 인스턴스에 속성으로 할당됩니다.

평균 컴포넌트 / 디렉티브 생성자는 의존성으로 인해 여러 줄 서명을 가질 수 있기 때문에 이미 충분히 크다. 불필요한 초기화 로직을 생성자 바디에 넣어 반 패턴에 기여한다.

비동기 초기화

비동기 초기화 생성자는 종종 반 패턴으로 간주 될 수 있으며 비동기 루틴이 수행되기 전에 클래스 인스턴스화가 완료되므로 경쟁 조건이 발생할 수 있습니다. 그렇지 않은 경우 ngOnInit, 특히 수명주기 후크가 더 나은 위치입니다. 특히 async구문의 이점을 얻을 수 있기 때문입니다 .

constructor(
  public foo: Foo,
  public errorHandler: ErrorHandler
) {}

async ngOnInit() {
  try {
    await this.foo.getBar();
    await this.foo.getBazThatDependsOnBar();
  } catch (err) {
    this.errorHandler.handleError(err);
  }
}

경쟁 조건 (구성 요소가 초기화 오류에 나타나지 않아야하는 조건 포함)이있는 경우 구성 요소 인스턴스화 전에 비동기 초기화 루틴을 수행하고 상위 구성 요소, 라우터 보호 장치 등으로 이동해야합니다.

단위 테스트

ngOnInit생성자보다 유연 하고이 답변 에서 자세히 설명하는 단위 테스트에 대한 몇 가지 이점을 제공합니다 .

ngOnInit단위 테스트에서 구성 요소 컴파일시 자동으로 호출되지 않는다는 점을 고려하면 ngOnInit구성 요소 인스턴스화 후 호출 된 메서드를 스파이하거나 조롱 할 수 있습니다.

예외적 ngOnInit으로 다른 구성 요소 단위 (예 : 일부 템플릿 논리)에 대한 격리를 제공하기 위해 완전히 스터 빙 될 수 있습니다.

계승

자식 클래스는 생성자를 대체 할 수 없으며 보강 할 수는 없습니다.

이후 this전에 참조 할 수 없습니다 super()초기화 우선 순위에이 풋 제한.

Angular 구성 요소 또는 지시문 ngOnInit이 시간에 영향을받지 않는 초기화 논리에 사용된다는 점을 고려하여 자식 클래스 super.ngOnInit()는 호출 여부 와시기를 선택할 수 있습니다 .

ngOnInit() {
  this.someMethod();
  super.ngOnInit();
}

생성자만으로는 구현할 수 없습니다.


12

위의 답변은 원래 질문 의이 측면에 실제로 대답하지 않습니다 : 수명주기 후크 란 무엇입니까? 이런 식으로 생각할 때까지 그 의미를 이해하는 데 시간이 걸렸습니다.

1) 구성 요소가 인간이라고 가정하십시오. 인간에게는 삶의 많은 단계를 포함하는 삶이 있으며 우리는 만료됩니다.

2) 우리의 인간 구성 요소는 다음과 같은 수명주기 스크립트를 가질 수 있습니다. 출생, 아기, 초등학교, 청년, 중년 성인, 노인, 사망, 처분.

3) 자녀를 만드는 기능을 원한다고 가정하십시오. 이것을 복잡하고 유머러스하게 만들지 않으려면 인간 구성 요소 수명의 청년 단계에서만 함수를 호출하기를 원합니다. 따라서 부모 구성 요소가 청년 단계에있을 때만 활성화되는 구성 요소를 개발합니다. 후크를 사용하면 삶의 단계를 알리고 구성 요소가 작동하도록 할 수 있습니다.

재미있는 것들. 상상력을 실제로 이런 식으로 코딩하게하면 복잡하고 재미 있습니다.


7

생성자는 자바 스크립트의 방법이며, 클래스가 바로이 코너 프레임 워크를 사용할지 여부를 생성자를 실행하거나이 자바 스크립트 엔진에 의해 호출됩니다 not.So와 각도가 더있다 인스턴스화 .When ES6의 클래스의 기능으로 간주됩니다 그것에 대한 통제.

import {Component} from '@angular/core';
@Component({})
class CONSTRUCTORTEST {

//This is called by Javascript not the Angular.
     constructor(){
        console.log("view constructor initialised");
     }
}

"ConstructorTest"클래스는 아래에 인스턴스화되어 있으므로 내부적으로 생성자를 호출합니다 (이 모든 것은 JavaScript (es6) no Angular에 의해 발생 함).

new CONSTRUCTORTEST();

이것이 Angular에 ngOnInit 라이프 사이클 후크 가있는 이유 입니다. Angular가 구성 요소 초기화를 완료하면 ngOnInit가 렌더링됩니다.

import {Component} from '@angular/core';
@Component({})
class NGONINITTEST implements onInit{
   constructor(){}
   //ngOnInit calls by Angular
   ngOnInit(){
     console.log("Testing ngOnInit");
   }
}

먼저 생성자 메서드를 즉시 실행하면 아래와 같이 클래스를 인스턴스화합니다.

let instance = new NGONINITTEST();

ngOnInit는 다음과 같이 필요할 때 Angular에 의해 호출됩니다.

instance.ngOnInit();

그러나 왜 Angular에서 생성자를 사용하고 있는지 물을 수 있습니다.

대답은 dependencies injections입니다 . 이전에 언급했듯이 클래스가 인스턴스화 될 때 즉시 JavaScript 엔진이 생성자를 호출하므로 (ngOnInit by Angular를 호출하기 전에) typescript는 생성자에 정의 된 종속성 유형을 얻는 데 도움이됩니다. 해당 특정 구성 요소에 사용하려는 종속성 유형


7

여기서 관찰해야 할 두 가지 :

  1. 생성자는 객체가 해당 클래스로 생성 될 때마다 호출됩니다.
  2. 구성 요소가 작성되면 ngOnInit가 호출됩니다.

둘 다 다른 유용성을 가지고 있습니다.


5

constructor () 는 구성 요소 수명주기의 기본 방법이며 종속성 주입에 사용됩니다. 생성자는 Typescript 기능입니다.

ngOnInit () 는 생성자 다음에 호출되고 ngOnInit는 첫 번째 ngOnChanges 후에 호출됩니다.

즉 :

생성자 () -->ngOnChanges () -->ngOnInit ()

위에서 언급 한 것처럼 ngOnChanges()입력 또는 출력 바인딩 값이 변경 될 때 호출됩니다.


4

두 방법 모두 목표 / 책임이 다릅니다. 생성자 (언어 지원 기능)의 작업은 표현이 변하지 않는지 확인하는 것입니다. 그렇지 않으면 멤버에 올바른 값을 제공하여 인스턴스가 올바른지 확인하십시오. '올바른'의 의미를 결정하는 것은 개발자의 몫입니다.

onInit () 메소드 (각 개념)의 태스크는 올바른 오브젝트 (표현 불변)에서 메소드 호출을 허용하는 것입니다. 각 메소드는 메소드가 종료 될 때 불변 표현이 유지되는지 확인해야합니다.

생성자는 '올바른'객체를 생성하는 데 사용해야하며 onInit 메소드는 잘 정의 된 인스턴스에서 메소드 호출을 호출 할 수있는 기회를 제공합니다.


4

생성자 : ES6 클래스 (이 경우 TypeScript)의 생성자 메소드는 Angular 피처가 아니라 클래스 자체의 피처입니다. 생성자가 호출 될 때 Angular의 제어를 벗어났습니다. 즉, Angular가 구성 요소 초기화를 완료 한 시점을 알려주는 것은 적합하지 않습니다. JavaScript 엔진은 Angular가 아닌 생성자를 직접 호출합니다. ngOnInit (및 AngularJS의 $ onInit) 라이프 사이클 후크가 작성된 이유입니다. 이를 염두에두고 생성자를 사용하기에 적합한 시나리오가 있습니다. 이것은 의존성 주입을 활용하고자 할 때입니다. 본질적으로 컴포넌트에 의존성을“연결”하기 위해.

생성자가 JavaScript 엔진에 의해 초기화되고 TypeScript를 사용하면 특정 속성에 대해 매핑해야하는 종속성을 Angular에 알릴 수 있습니다.

ngOnInit 는 순전히 Angular가 구성 요소 초기화를 완료했다는 신호를 제공합니다.

이 단계에는 @Input () 데코레이터를 사용하는 등 구성 요소 자체에 바인딩 할 수있는 속성에 대한 변경 감지의 첫 번째 단계가 포함됩니다.

이로 인해 @Input () 속성은 ngOnInit 내에서 사용할 수 있지만 생성자 내에서 의도적으로 정의되지 않았습니다.


2

생성자가 첫 번째이며 @input 데이터가 null 일 때 가끔 발생합니다! 그래서 우리는 Constructor를 선언 서비스에 사용하고 ngOnInit는 이후에 발생합니다. contrutor의 샘플 :

 constructor(translate: TranslateService, private oauthService: OAuthService) {
    translate.setDefaultLang('En');
        translate.use('En');}

onInit에 대한 예제 :

ngOnInit() {
    this.items = [
      { label: 'A', icon: 'fa fa-home', routerLink: ['/'] },
      { label: 'B', icon: 'fa fa-home', routerLink: ['/'] }]
}

onInit은 winForm의 InitialComponents ()와 같다고 생각합니다.


1

각도 수명주기에서

1) 각도 인젝터는 생성자 매개 변수를 감지하고 클래스를 인스턴스화합니다.

2) 다음 각도 호출 수명주기

각도 수명주기 후크

ngOnChanges-> 지시문 매개 변수 바인딩을 호출합니다.

ngOnInit-> 각도 렌더링 시작 ...

각도 수명주기의 상태로 다른 메소드를 호출하십시오.


1

constructor때 각도 "instanciates / 구조"구성 요소라고합니다. 이 ngOnInit방법은 구성 요소 수명주기의 초기화 부분을 나타내는 후크입니다. 모범 사례는 서비스 주입 에만 사용하는 것입니다 .

constructor(private 
    service1: Service1,
    service2: Service2
){};

가능하더라도 내부에서 "일"을해서는 안됩니다. 컴포넌트 "초기화"에서 발생해야하는 작업을 시작하려면 ngOnInit다음을 사용하십시오 .

ngOnInit(){
    service1.someWork();
};

또한 상위 구성 요소에서 오는 입력 특성 과 관련된 조치 는 컨스트럭터에서 수행 할 수 없습니다. 그들은 ngOnInit방법이나 다른 고리에 배치해야합니다 . 뷰와 관련된 요소 (DOM)와 동일합니다 (예 : viewchild 요소) .

@Input itemFromParent: string;
@ViewChild('childView') childView;

constructor(){
    console.log(itemFromParent); // KO
    // childView is undefined here
};

ngOnInit(){
    console.log(itemFromParent); // OK
    // childView is undefined here, you can manipulate here
};

0

constructor() 의존성 주입을 수행하는 데 사용됩니다.

ngOnInit(), ngOnChanges()ngOnDestroy()등주기 방법이다. ngOnChanges()전에 호출 할 첫 번째 일 것이다 ngOnInit()변화가없는 경우 바운드 속성 값이 변경, 그것은 호출되지 않습니다 때,. ngOnDestroy()구성 요소가 제거 될 때 호출됩니다. 그것을 사용하려면 클래스에 의해 에드가 OnDestroy필요합니다 implement.


1
동의합니다. 이것은 짧고 명확합니다. 예를 들어 constructor ()은 서비스 객체를 추가하기위한 것이고 ngOnInit ()는 필요한 서비스 함수 호출을 가진 컴포넌트를 조작하기위한 것입니다.
Steve

0

나는 그 답을 찾았고 그것을 영어로 번역하려고 노력했다.이 질문은 여전히 ​​기술 인터뷰에서도 발생했다. 사실, 둘 사이에는 큰 유사점이 있지만 약간의 차이점도 있습니다.

  • 생성자는 ECMAScript의 일부입니다. 반면에 ngOnInit ()은 각도의 개념입니다.

  • Angular를 사용하지 않더라도 모든 클래스에서 생성자를 호출 할 수 있습니다

  • LifeCycle : 생성자가 ngOnInt () 전에 호출됩니다.

  • 생성자에서 HTML 요소를 호출 할 수 없습니다. 그러나 ngOnInit ()에서는 가능합니다.

  • 일반적으로 생성자가 아닌 ngOnInit ()에서 서비스 호출

    출처 : http://www.angular-tuto.com/Angular/Component#Diff


0

건설자

생성자 함수는 모든 클래스와 함께 제공되며 생성자는 Angular에만 국한된 것이 아니라 객체 지향 디자인에서 파생 된 개념입니다. 생성자는 구성 요소 클래스의 인스턴스를 만듭니다.

OnInit

ngOnInit함수는 Angular 구성 요소의 수명주기 방법 중 하나입니다. Angular 구성 요소의 수명주기 방법 (또는 후크)을 사용하면 구성 요소 수명의 여러 단계에서 코드를 실행할 수 있습니다. 생성자 메서드와 달리 ngOnInit메서드는 OnInit이 메서드를 사용하기 위해 구성 요소가 구현해야하는 Angular 인터페이스 ( ) 에서 제공됩니다 . 이 ngOnInit메소드는 컴포넌트가 작성된 직후에 호출됩니다.


0

생성자는 클래스가 인스턴스화 될 때 실행됩니다. 각도와 관련이 없습니다. Javascript의 기능이며 Angular는 제어 할 수 없습니다

ngOnInit는 Angular에 특정하며 Angular가 모든 입력 속성으로 구성 요소를 초기화했을 때 호출됩니다.

@Input 속성은 ngOnInit 수명주기 후크에서 사용할 수 있습니다. 이것은 백엔드 서버에서 데이터를 가져 와서 뷰에 표시하는 것과 같은 초기화 작업을 수행하는 데 도움이됩니다.

@Input 속성은 생성자 내부에 정의되지 않은 것으로 표시됩니다


-1

생성자 는 컴포넌트 (또는 다른 클래스)가 빌드 될 때 실행되는 함수입니다.

ngOnInit 는 컴포넌트 라이프 사이클 메소드 그룹에 속하는 함수이며 컴포넌트의 다른 순간에 실행됩니다 (따라서 이름 라이프 사이클). 다음은 모든 목록입니다.

여기에 이미지 설명을 입력하십시오 생성자는 수명주기 기능 전에 실행됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.