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



Answers

최고의 사례는 서비스를 사용하는 것이라고 생각합니다. 구성 요소가 '활성화 됨'상태가되면 서버에서 데이터를 가져 오려고한다고 가정 해 보겠습니다. 서버에서 가져온 데이터에 대해 몇 가지 추가 작업을 수행하려고합니다. 오류가 발생하여이를 다르게 기록하려고합니다.

생성자에 대해 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를 채울 수는 있지만 어쩌면 그저 몇 가지 추가 작업을 수행하려고 할 수 있습니다. 모든 것이 upper_case인지 확인하는 것과 같이, 나는 내 데이터가 어떻게 전달되는지 완전히 확신하지 못한다.

따라서 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();
    };


}

그것은 훨씬 더 쉽게 볼 수있게 해줍니다. 그래서 다른 곳을 찾아야하는 대신 초기화 할 때 구성 요소 내에서 함수를 호출합니다. 실제로는 앞으로 더 쉽게 읽고 사용할 수있게 해주는 또 다른 도구 일뿐입니다. 또한 생성자 내에서 함수 호출을 넣는 것은 정말 나쁜 습관입니다!

Question

Angular는 기본적으로 라이프 사이클 후크 ngOnInit 을 제공합니다.

우리가 이미 constructor 가지고 있다면 ngOnInit 사용해야하는 이유는 무엇입니까?




위의 설명에서 생략 된 중요한 사항 하나를 추가하고 ngOnInit반드시 사용 ngOnInit 설명합니다.

예를 들어 ViewChildren , ContentChildren 또는 ElementRef 를 통해 구성 요소의 DOM을 조작하는 경우 생성자 단계에서 네이티브 요소를 사용할 수 없습니다.

그러나 ngOnInit 은 구성 요소가 만들어지고 ngOnChanges ( ngOnChanges )가 호출되면 발생 ngOnChanges 시점에서 DOM에 액세스 할 수 있습니다.

export class App implements OnInit {
  @ViewChild('myTemplate') myTemplate: TemplateRef<any>;

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

  ngOnInit() {
     // this.elementRef.nativeElement can be used from here on
     // this.myTemplate can be used from here on
  }
}



간단하고 간단한 대답은,

Constructor : constructor 는 구성 요소가 생성 될 때 default method 가 실행됩니다 ( deafult로 실행 ). 시간의 constructor(default method) 클래스 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 후크

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




생성자 : ES6 클래스 (이 경우 TypeScript)의 생성자 메서드는 Angular 기능이 아닌 클래스 자체의 기능입니다. Angular가 생성자를 호출 할 때 제어권을 벗어났습니다. Angular가 구성 요소 초기화를 마쳤을 때 알려주는 것은 적절하지 않습니다. JavaScript 엔진은 Angular가 아닌 생성자를 직접 호출합니다. 그래서 ngOnInit (및 AngularJS의 $ onInit) 라이프 사이클 후크가 만들어졌습니다. 이를 염두에두고, 생성자를 사용하기에 적합한 시나리오가 있습니다. 종속성 주입을 활용하려는 경우입니다. 기본적으로 종속성을 구성 요소에 "연결"하기위한 것입니다.

생성자는 JavaScript 엔진에 의해 초기화되고 TypeScript는 Angular에게 특정 속성에 대해 매핑해야하는 종속성을 알려줍니다.

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

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

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




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

  1. 생성자는 해당 클래스의 객체가 만들어 질 때마다 호출됩니다.
  2. ngOnInit은 구성 요소가 만들어지면 호출됩니다.

둘 다 다른 유용성이 있습니다.




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

두 번째는 Angular2 구성 요소의 라이프 사이클 후크에 해당합니다.

공식 앵거스 웹 사이트에서 인용 :

  • ngOnChanges 는 입력 또는 출력 바인딩 값이 변경 될 때 호출됩니다.
  • ngOnInit 은 첫 번째 ngOnChanges 뒤에 호출 ngOnChanges

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




각도 수명주기

1) 각도 주사기는 생성자 매개 변수 (s)를 감지하고 클래스를 인스턴스화합니다.

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

각 수명주기 후크

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

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

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




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

실질적인 차이점은 ngOnInit 이 코드가 어떻게 구성 ngOnInit 영향을줍니다. 대부분의 초기화 코드는 경쟁 조건을 생성하지 않는 한 ngOnInit 으로 이동할 수 있습니다.

생성자 반 패턴 생성자

상당한 양의 초기화 코드는 생성자 메서드를 읽기 및 테스트하기가 어렵습니다.

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

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

ngOnInit() {
  // rest of initialization code
}

의존성 주입

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

평균 구성 요소 / 지시문 생성자는 종속성으로 인해 여러 줄 서명을 가질 수 있기 때문에 이미 충분히 크므로 생성자 본문에 불필요한 초기화 논리를 배치하면 반 패턴에 기여합니다.

단위 테스트

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

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

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

계승

하위 클래스는 생성자 만 대체 할 수는 있지만 생성자를 대체 할 수는 없습니다.

super() 전에 참조 할 수 없으므로 초기화 우선 순위에 제한이 있습니다.

각도 구성 요소 / 지시문이 시간에 민감하지 않은 초기화 논리에 ngOnInit 을 사용 ngOnInit 할 때 하위 클래스는 super.ngOnInit() 이 호출되는지 여부와 언제 선택할 수 있습니다.

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

이것은 생성자만으로 구현하는 것은 불가능합니다.




위의 답변은 원래 질문의이 측면에 실제로 대답하지 않습니다. 라이프 사이클 후크는 무엇입니까? 이 방법을 생각할 때까지 그 의미가 무엇인지 이해하는 데는 시간이 걸렸습니다.

1) 구성 요소가 사람이라고 가정 해보십시오. 인간은 여러 단계의 삶을 포함하는 삶을 살고 있으며 그 후에 만료됩니다.

2) 우리의 인간 구성 요소는 태어난 아기, 초등 학교, 청년, 중년 성인, 고령자, 죽은 사람, 처형 된 다음과 같은 라이프 사이클 스크립트를 가질 수 있습니다.

3) 자녀를 만드는 기능을 원한다고 가정 해보십시오. 이것을 복잡하게하지 않고 유머러스하게 유지하려면 인간 구성 요소 수명의 청년기에만 함수를 호출해야합니다. 따라서 상위 구성 요소가 청년 단계에있을 때만 활성화되는 구성 요소를 개발합니다. 후크는 그 단계의 삶에 신호를 보내고 구성 요소가 그것에 영향을 미치도록하여 도움을줍니다.

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




Related