1342

Angular はngOnInitデフォルトでライフサイクル フックを提供します。

ngOnInit既に ? があるのに、なぜ使用する必要があるのconstructorですか?

4

27 に答える 27

1346

これConstructorは、クラスがインスタンス化されるときに実行されるクラスのデフォルト メソッドであり、クラスとそのサブクラスのフィールドが適切に初期化されるようにします。Angular、またはより良い Dependency Injector (DI) は、コンストラクター パラメーターを分析し、呼び出しnew MyClass()て新しいインスタンスを作成するときに、コンストラクター パラメーターの型に一致するプロバイダーを見つけようとし、それらを解決してコンストラクターに渡します。

new MyClass(someArg);

ngOnInitAngular がコンポーネントの作成を完了したことを示すために 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() は「開始」するのに適した場所です。コンポーネントのバインディングが解決される場所/時期です。

詳細については、次を参照してください。

于 2016-03-03T05:20:08.773 に答える
68

最初のもの (コンストラクター) は、クラスのインスタンス化に関連しており、Angular2 とは関係ありません。つまり、コンストラクターはどのクラスでも使用できます。新しく作成されたインスタンスの初期化処理を入れることができます。

2 つ目は、Angular2 コンポーネントのライフサイクル フックに対応します。

angularの公式Webサイトから引用:

  • ngOnChanges入力または出力バインディングの値が変更されたときに呼び出されます
  • ngOnInit最初の後に呼び出されますngOnChanges

したがってngOnInit、初期化処理がコンポーネントのバインディングに依存する場合 (たとえば、 で定義されたコンポーネント パラメータ@Input) を使用する必要があります。それ以外の場合は、コンストラクタで十分です...

于 2016-03-03T06:36:10.717 に答える
44

短くて簡単な答えは、

Constructor:コンポーネントが構築されているときに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 フック

両方の実装を示すこの小さなデモを確認できます。

于 2016-03-03T05:20:58.590 に答える
22

これをテストするために、 NativeScript チュートリアルから借りて、次のコードを書きました。

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 ***  
于 2016-05-24T14:58:31.430 に答える
7

コンストラクター: ES6 クラス (この場合は TypeScript) のコンストラクター メソッドは、Angular の機能ではなく、クラス自体の機能です。コンストラクターが呼び出されたとき、これは Angular の制御外です。つまり、Angular がコンポーネントの初期化を完了したことを知らせる適切なフックではありません。JavaScript エンジンは、Angular を直接呼び出すのではなく、コンストラクターを呼び出します。これが、ngOnInit (および AngularJS の $onInit) ライフサイクル フックが作成された理由です。これを念頭に置いて、コンストラクターを使用するための適切なシナリオがあります。これは、依存性注入を利用したい場合です。基本的には、依存性をコンポーネントに「結び付ける」ために使用します。

コンストラクターは JavaScript エンジンによって初期化されるため、TypeScript を使用すると、特定のプロパティに対してマップする必要がある依存関係を Angular に伝えることができます。

ngOnInitは純粋に、Angular がコンポーネントの初期化を完了したというシグナルを提供するために存在します。

このフェーズには、 @Input() デコレータの使用など、コンポーネント自体にバインドできるプロパティに対する変更検出の最初のパスが含まれます。

このため、@Input() プロパティは ngOnInit 内で使用できますが、設計上、コンストラクター内では未定義です。

于 2017-12-20T06:47:24.773 に答える
1

constructor、Angular がコンポーネントを「インスタンス化/構築」するときに呼び出されます。メソッドは、コンポーネントの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
};
于 2019-01-18T12:23:49.140 に答える
0

コンストラクターは、Typescript クラスによって提供されるデフォルトのメソッドであり、クラス メンバーの初期化専用であり、通常、上記のサンプル コードのような依存関係注入サービス、またはタイマーの初期化、ソケット接続の初期化に使用されます。

export class AppComponent {
  title = 'angular-fork-join';
  constructor(private http: HttpClient) {}

ngOnInit : コンポーネントが初期化されるときに呼び出されるライフサイクル フックであり、ビジネス ロジック、データの初期化、API 呼び出しなどに特化した Angular によって提供されます。API 呼び出しを示すサンプル コード:

export class HomeComponent implements OnInit {

  products = [];

  constructor(private dataService: DataService) { }

  ngOnInit() {

    this.dataService.sendGetRequest().subscribe((data: any[])=>{
      console.log(data);
      this.products = data;
    })  
  }

} 
于 2021-07-13T19:44:42.637 に答える