ความแตกต่างระหว่าง Constructor และ ngOnInit


1072

เชิงมุมให้เบ็ดวงจรชีวิตngOnInitโดยค่าเริ่มต้น

ทำไมngOnInitต้องใช้ถ้าเรามีconstructor?


11
เฮ้ลองอ่านคำตอบของฉันที่อธิบายถึงความแตกต่างจากมุมมองของผลงานภายในของ Angular
Max Koretskyi


1
@ MaximKoretskyi ลิงก์ของคุณเสียชีวิต
Yash Capoor

คำตอบ:


1108

Constructorเป็นวิธีการเริ่มต้นของการเรียนที่มีการดำเนินการเมื่อชั้นถูกสร้างและสร้างความมั่นใจ initialisation ที่เหมาะสมของเขตข้อมูลในชั้นเรียนและ subclasses ของมัน Angular หรือดีกว่า Dependency Injector (DI) วิเคราะห์พารามิเตอร์ Constructor และเมื่อมันสร้างอินสแตนซ์ใหม่โดยการเรียกnew MyClass()มันจะพยายามค้นหาผู้ให้บริการที่ตรงกับประเภทของพารามิเตอร์ Constructor แก้ไขพวกมันและส่งมันไปยัง Constructor เช่น

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 มีพวกเขา) ตัวสร้างไม่เกี่ยวข้องกับ Angular2 ซึ่งเป็นคุณลักษณะของ TypeScript Angular Lifecycle hooks ถูกเรียกโดย Angular หลังจากการเริ่มต้นบางอย่างเกิดขึ้นหรือเมื่อมีเหตุการณ์บางอย่างเกิดขึ้นเพื่อให้ส่วนประกอบทำหน้าที่ในบางสถานการณ์และให้โอกาสในการทำงานบางอย่างในเวลาที่เหมาะสม
GünterZöchbauer

12
มีคำพูดบล็อกอยู่ในangular.io/docs/ts/latest/guide/server-communication.htmlที่อธิบายสิ่งนี้: "ส่วนประกอบง่ายต่อการทดสอบและดีบักเมื่อตัวสร้างง่ายและทำงานจริงทั้งหมด (โดยเฉพาะการเรียก เซิร์ฟเวอร์ระยะไกล) ได้รับการจัดการในวิธีการแยกต่างหาก " - ในกรณีนี้เมธอดคือ ngOnInit ()
yoonjesung

3
เป็นเบ็ดวงจรชีวิตที่เรียกโดย Angular2 เพื่อบ่งชี้ว่า Angular เสร็จสิ้นการสร้างส่วนประกอบ - นั่นไม่ใช่อย่างนั้น มันส่งสัญญาณว่ามันเริ่มต้นการผูก ส่วนประกอบถูกสร้างขึ้นก่อนหน้านี้ ดูคำตอบของฉัน
Max Koretskyi

22
เช่นเดียวกับ "แนวปฏิบัติที่ดีที่สุด" ฉันคิดว่าเป็นความคิดที่ดีที่จะอธิบายว่าทำไมคุณไม่ควรทำ "งาน" ในตัวสร้าง บทความนี้นำโดยทีมงานเชิงมุมมีความหนาแน่นสูง แต่อาจช่วยได้: misko.hevery.com/code-reviewers-guide/ ...... นอกจากนี้ควรวางความสำคัญน้อยลงบนคาถาที่จำเป็นในการใช้งาน OnInit (หาง่าย) และอื่น ๆ อีกมากมาย ความจริงที่สำคัญที่การเชื่อมโยงข้อมูลไม่พร้อมใช้งานในตัวสร้าง
Reikim

2
ถ้าอยู่ในโหมดที่เข้มงวดเป็นจริงในtsconfig.jsonไฟล์เช่น"strict": trueนั้นคุณจะต้องเริ่มต้นสมาชิกชั้นในconstructorไม่ได้อยู่ในเช่นngOnit FormGroup
Rohit Sharma

169

บทความความแตกต่างที่สำคัญระหว่าง Constructor และ ngOnInit ใน Angularสำรวจความแตกต่างจากหลายมุมมอง คำตอบนี้ให้คำอธิบายความแตกต่างที่สำคัญที่สุดที่เกี่ยวข้องกับกระบวนการกำหนดค่าเริ่มต้นขององค์ประกอบซึ่งแสดงการใช้งานที่แตกต่างกัน

กระบวนการบูทสแตรปแบบ Angular ประกอบด้วยสองขั้นตอนหลัก:

  • การสร้างส่วนประกอบของต้นไม้
  • ใช้การตรวจจับการเปลี่ยนแปลง

ตัวสร้างของส่วนประกอบถูกเรียกเมื่อทรีแองกูลาร์สร้างส่วนประกอบของต้นไม้ ตะขอวงจรชีวิตทั้งหมดเรียกว่าเป็นส่วนหนึ่งของการตรวจจับการเปลี่ยนแปลงการเรียกใช้

เมื่อแองกูลาร์สร้างส่วนประกอบต้นไม้โมดูลรูทของหัวฉีดได้รับการกำหนดค่าไว้แล้วเพื่อให้คุณสามารถฉีดการพึ่งพาทั่วโลก นอกจากนี้เมื่อ Angular สร้างอินสแตนซ์คลาสของคอมโพเนนต์ลูกอินเจ็คเตอร์สำหรับคอมโพเนนต์พาเรนต์ก็ตั้งค่าไว้แล้วดังนั้นคุณจึงสามารถฉีดผู้ให้บริการที่กำหนดไว้ในคอมโพเนนต์หลักรวมถึงองค์ประกอบหลักเอง ตัวสร้างส่วนประกอบเป็นวิธีการเดียวที่เรียกว่าในบริบทของหัวฉีดดังนั้นหากคุณต้องการการพึ่งพาใด ๆ นั่นเป็นเพียงที่เดียวที่จะได้รับการอ้างอิงเหล่านั้น

เมื่อ Angular เริ่มเปลี่ยนการตรวจจับต้นไม้ส่วนประกอบจะถูกสร้างขึ้นและตัวสร้างสำหรับส่วนประกอบทั้งหมดในต้นไม้ได้ถูกเรียก นอกจากนี้ยังมีส่วนประกอบของทุกโหนดแม่แบบจะมีการเพิ่ม DOM @Inputกลไกการสื่อสารมีการประมวลผลในระหว่างการตรวจสอบการเปลี่ยนแปลงเพื่อให้คุณไม่สามารถคาดหวังที่จะมีคุณสมบัติที่มีอยู่ในตัวสร้าง ngOnInitมันจะมีอยู่บนหลัง

มาดูตัวอย่างด่วน สมมติว่าคุณมีเทมเพลตต่อไปนี้:

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

ดังนั้น Angular เริ่มการบูตแอปพลิเคชัน ที่ผมกล่าวว่ามันเป็นครั้งแรกสร้างชั้นเรียนสำหรับแต่ละองค์ประกอบ ดังนั้นมันจึงเรียกคอนMyAppComponentสตรัคเตอร์ นอกจากนี้ยังสร้างโหนด DOM ซึ่งเป็นองค์ประกอบโฮสต์ของmy-appองค์ประกอบ จากนั้นจะดำเนินการสร้างองค์ประกอบโฮสต์สำหรับchild-compและเรียกคอนChildComponentสตรัค ในขั้นตอนนี้ไม่เกี่ยวข้องกับการiเชื่อมโยงอินพุตและวงจรชีวิตใด ๆ ดังนั้นเมื่อกระบวนการนี้เสร็จสิ้น Angular จะจบลงด้วยทรีของมุมมองคอมโพเนนต์ต่อไปนี้:

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

จากนั้นเรียกใช้การตรวจจับการเปลี่ยนแปลงและอัปเดตการเชื่อมโยงสำหรับmy-appและการโทรngOnInitบนคลาส MyAppComponent จากนั้นจะดำเนินการอัพเดตการเชื่อมโยงสำหรับchild-compและเรียกngOnInitใช้คลาส ChildComponent

คุณสามารถทำตรรกะของคุณเริ่มต้นในตัวสร้างหรือngOnInitขึ้นอยู่กับสิ่งที่คุณต้องการใช้ได้ ตัวอย่างบทความนี่คือวิธีการรับ ViewContainerRef ก่อนการประเมิน @ViewChild แบบสอบถามแสดงประเภทของตรรกะการเริ่มต้นที่จะต้องดำเนินการในตัวสร้าง

นี่คือบทความบางส่วนที่จะช่วยให้คุณเข้าใจหัวข้อได้ดีขึ้น:


33
นี่ควรเป็นคำตอบที่ยอมรับได้ 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 ทำไม AppComponentOnInit จะถูกเรียกว่าก่อน ChildComponentConstructor
user2485435

1
@ MaxKoretskyiaka ตัวช่วยสร้างคุณถูกต้อง ฉันทำผิดพลาดบางอย่างในการตั้งค่าแอปพลิเคชันของฉัน มันทำงานได้ตามที่คุณอธิบายไว้ angular-c7zjsx.stackblitz.io
user2485435

93

ฉันคิดว่าตัวอย่างที่ดีที่สุดคือการใช้บริการ สมมติว่าฉันต้องการคว้าข้อมูลจากเซิร์ฟเวอร์ของฉันเมื่อส่วนประกอบของฉันได้รับ 'เปิดใช้งาน' สมมติว่าฉันต้องการทำสิ่งเพิ่มเติมบางอย่างกับข้อมูลหลังจากที่ฉันได้รับจากเซิร์ฟเวอร์บางทีฉันอาจได้รับข้อผิดพลาดและต้องการเข้าสู่ระบบที่แตกต่างกัน

มันง่ายมากที่จะมี ngOnInit ผ่าน Constructor และมันก็ จำกัด จำนวนการโทรกลับของเลเยอร์ที่ฉันต้องการเพิ่มลงในแอปพลิเคชันของฉัน

ตัวอย่างเช่น:

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


}

กับ constructor ของฉันฉันสามารถโทรหาผู้ใช้ _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();
    };


}

มันทำให้มองเห็นได้ง่ายขึ้นและดังนั้นฉันจึงเรียกฟังก์ชันของฉันในองค์ประกอบของฉันเมื่อฉันเริ่มต้นแทนที่จะต้องขุดหาที่อื่น จริงๆแล้วเป็นเพียงเครื่องมืออีกอย่างที่คุณสามารถใช้เพื่อให้อ่านและใช้งานได้ง่ายขึ้นในอนาคต นอกจากนี้ฉันคิดว่ามันเป็นการปฏิบัติที่ไม่ดีจริงๆที่จะนำการเรียกใช้ฟังก์ชันภายในตัวสร้าง!


ตัวอย่างของคุณอาจง่ายขึ้นหากคุณเพิ่งตั้งค่า user_list เป็น Observable Angular2 มีท่อ async ดังนั้นจึงไม่มีปัญหาใด ๆ
DarkNeuron

@ มอร์แกนเพียงแค่ให้ฉันเรียนรู้สิ่งเล็ก ๆ ที่นี่ทำไมคุณสร้างฟังก์ชั่นgetUsersก่อนแล้วจึงใส่มันเข้าไปngOnInit? มันไม่น้อยรหัสที่จะเขียนใน ngOnInit? ฉันกำลังสงสัยว่าทำไมผู้คนถึงทำแบบนี้? เป็นเช่นนั้นหรือไม่หากคุณต้องการใช้รหัสซ้ำอีกครั้ง ขอบคุณ
Alfa Bravo

31
เท่าที่เห็นในคำตอบด้านล่างนี้ไม่สร้างความแตกต่างถ้ามันอยู่ในตัวสร้าง นี่ไม่ใช่คำตอบที่แท้จริงสำหรับวัตถุประสงค์
Jimmy Kane

8
ฉันไม่เห็นว่าสิ่งนี้ตอบคำถามได้อย่างไร ทำไมคุณไม่ใส่รหัสลงไปconstructor?
CodyBugstein

1
@ มอร์แกนเหตุใดคุณไม่สามารถทำได้constructor(private _userService: UserService){ this.getUsers(); };
แอชลีย์

82

ตกลงก่อนอื่นngOnInitเป็นส่วนหนึ่งของวงจรชีวิตเชิงมุมในขณะที่constructorเป็นส่วนหนึ่งของคลาสES6 JavaScript ดังนั้นความแตกต่างที่สำคัญเริ่มต้นที่นี่! ...

ดูแผนภูมิด้านล่างที่ฉันสร้างซึ่งแสดงวงจรชีวิตของ Angular

ngOnInit กับตัวสร้าง

ใน Angular2 + เราใช้constructorในการทำDI(Dependency Injection)เพื่อเราในขณะที่ Angular 1 มันเกิดขึ้นผ่านการโทรไปยังวิธีการ String และตรวจสอบว่าการพึ่งพาใดถูกฉีด

ดังที่คุณเห็นในแผนภาพด้านบนngOnInitเกิดขึ้นหลังจากตัวสร้างพร้อมและngOnChnagesถูกไล่ออกหลังจากส่วนประกอบพร้อมสำหรับเรา การเริ่มต้นทั้งหมดสามารถเกิดขึ้นได้ในขั้นตอนนี้ตัวอย่างง่ายๆคือการฉีดเซอร์วิสและเริ่มต้นด้วย init

ตกลงฉันยังแชร์รหัสตัวอย่างเพื่อให้คุณดูดูวิธีการใช้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ใช้

หากคุณทำการจัดการ DOM ขององค์ประกอบผ่านทางViewChildren , ContentChildrenหรือElementRefองค์ประกอบดั้งเดิมของคุณจะไม่สามารถใช้ได้ในช่วงตัวสร้าง

อย่างไรก็ตามเนื่องจาก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
Nope สำหรับ@ViewChildrenโดยเฉพาะอย่างยิ่งที่คุณจำเป็นต้องใช้ngAfterViewInitวิธีการ ดูที่นี่: stackoverflow.com/questions/46314734/…
AsGoodAsItGets

1
ขอบคุณ @AsGoodAsItGets ที่ชี้ให้เห็น ตอนนี้ฉันได้ปรับปรุงคำตอบแล้ว
Miroslav Jonas

38

คำตอบที่สั้นและง่ายจะเป็น

Constructor: constructoris a default methodrun ( โดย deafult ) เมื่อมีการสร้างส่วนประกอบ เมื่อคุณสร้างan instanceชั้นเรียนในเวลานั้นก็constructor(default method)จะถูกเรียกว่า ดังนั้นในคำอื่น ๆ เมื่อองค์ประกอบจะถูกconstructed or/and an instance is created constructor(default method)เรียกและรหัสที่เกี่ยวข้องภายในถูกเรียกว่า โดยทั่วไปและโดยทั่วไปAngular2จะใช้ในการฉีดสิ่งต่าง ๆ เช่นservicesเมื่อมีการสร้างส่วนประกอบสำหรับการใช้งานเพิ่มเติม

OnInit: ngOnInit เป็นเบ็ดวงจรชีวิตของส่วนประกอบที่ทำงานครั้งแรกหลังจากที่constructor(default method)เมื่อองค์ประกอบจะถูกเริ่มต้น

ดังนั้น Constructor ของคุณจะถูกเรียกก่อนและ Oninit จะถูกเรียกในภายหลังหลังจาก Constructor Method

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
ฉันคิดว่า "ตัวสร้างเป็นสิ่งที่เรียกใช้หรือเรียกใช้เมื่อเริ่มต้นองค์ประกอบ" กำลังทำให้เข้าใจผิด ตัวสร้างเป็นคุณลักษณะของคลาสที่ไม่ใช่ส่วนประกอบ ฉันจะบอกว่าอินสแตนซ์ของคลาสเป็นเพียงส่วนประกอบหลังจากคอนสตรัคเตอร์ถูกเรียกและแองกูลาร์ก็เริ่มต้นมัน
GünterZöchbauer

ใช่เปลี่ยนคำสั่งที่คุณสามารถตรวจสอบได้ในขณะนี้
micronyks

1
อืม IMHO มันยังคงเป็น "ตัวสร้าง (วิธีการเริ่มต้น) เดียวกันซึ่งเป็นสิ่งที่เรียกใช้หรือเรียกใช้เมื่อมีการสร้างส่วนประกอบ" มันไม่เพียง แต่เรียกว่าเมื่อส่วนประกอบถูกสร้าง แต่ยังสำหรับบริการหรือเมื่อมีnew MyClass()การเรียกใช้รหัสเช่น ฉันคิดว่ามันเป็นความเข้าใจผิดที่จะบอกว่าคอนสตรัคเตอร์นั้นเกี่ยวกับส่วนประกอบพวกมันเกี่ยวกับคลาสและการเริ่มต้นอินสแตนซ์ของคลาสเหล่านี้ ส่วนประกอบเกิดขึ้นเป็นคลาสดังกล่าว มิฉะนั้นฉันคิดว่ามันเป็นคำตอบที่ดี
GünterZöchbauer

2
ใช่อย่างแน่นอน ลืมพูดถึงว่าเมื่อคุณสร้างวัตถุของชั้นเรียนด้วยเวลานั้นconstructorจะถูกเรียกว่า แต่คำตอบนี้เขียนขึ้นในบริบทของ angular2 หากต้องการทราบคำตอบที่ดีที่สุดคุณจะต้องรู้พื้นฐานของ OOP ยังฉันจะอัปเดตคำตอบ
micronyks

@ GünterZöchbauerผมไม่คิดว่ามันเป็นคำยืนยันที่ถูกต้องที่เป็นคุณลักษณะของชั้นไม่ได้ขององค์ประกอบ จากมุมมองภาษาการเขียนโปรแกรมใช่สิ่งนี้ถูกต้อง แต่ฉันสามารถทำงานกับส่วนประกอบได้อย่างประสบความสำเร็จโดยไม่มีวงจรชีวิตใด ๆ เลย แต่ฉันไม่สามารถทำงานกับส่วนประกอบที่ไม่มีคอนสตรัคเตอร์ได้ถ้าฉันต้องการ DI เพราะมันเป็นที่เดียวที่ฉีดได้ ดูคำตอบของฉัน
Max Koretskyi

20

เช่นเดียวกับภาษาอื่น ๆ มากมายคุณสามารถกำหนดค่าเริ่มต้นของตัวแปรที่ระดับคลาสตัวสร้างหรือเมธอด ขึ้นอยู่กับผู้พัฒนาที่จะตัดสินใจว่าอะไรดีที่สุดในกรณีของพวกเขา แต่ด้านล่างเป็นรายการแนวทางปฏิบัติที่ดีที่สุดเมื่อต้องตัดสินใจ

ตัวแปรระดับชั้นเรียน

โดยปกติแล้วคุณจะประกาศตัวแปรทั้งหมดของคุณที่นี่ซึ่งจะถูกใช้ในองค์ประกอบที่เหลือของคุณ คุณสามารถเริ่มต้นได้หากค่าไม่ได้ขึ้นอยู่กับสิ่งอื่นหรือใช้คำหลัก const เพื่อสร้างค่าคงที่หากพวกเขาจะไม่เปลี่ยนแปลง

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

นวกรรมิก

โดยปกติแล้วมันเป็นแนวปฏิบัติที่ดีที่สุดที่จะไม่ทำอะไรเลยในนวกรรมิกและใช้สำหรับคลาสที่จะถูกฉีด ส่วนใหญ่คอนสตรัคของคุณควรมีลักษณะเช่นนี้:

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

สิ่งนี้จะสร้างตัวแปรระดับชั้นเรียนโดยอัตโนมัติดังนั้นคุณจะสามารถเข้าถึงได้customService.myMethod()โดยไม่ต้องทำด้วยตนเอง

NgOnInit

NgOnit เป็น lifecycle hook ที่จัดทำโดย Angular 2 framework ส่วนประกอบของคุณจะต้องใช้งานOnInitเพื่อที่จะใช้มัน วงจรชีวิตของ hook นี้ถูกเรียกหลังจากคอนสตรัคเตอร์ถูกเรียกใช้และตัวแปรทั้งหมดจะเริ่มต้นได้ ส่วนใหญ่ของการเริ่มต้นของคุณควรไปที่นี่ คุณจะมีความมั่นใจว่า Angular ได้เริ่มต้นองค์ประกอบของคุณอย่างถูกต้องและคุณสามารถเริ่มทำตรรกะใด ๆ ที่คุณต้องการOnInitเมื่อเทียบกับการทำสิ่งต่าง ๆ เมื่อส่วนประกอบของคุณโหลดไม่เสร็จ

นี่คือภาพที่แสดงลำดับของสิ่งที่ถูกเรียก:

ป้อนคำอธิบายรูปภาพที่นี่

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

TLDR

หากคุณกำลังใช้เฟรมเวิร์ก Angular 2 และต้องการโต้ตอบกับเหตุการณ์รอบระยะเวลาหนึ่งให้ใช้วิธีการที่กำหนดโดยเฟรมเวิร์กสำหรับสิ่งนี้เพื่อหลีกเลี่ยงปัญหา


19

เพื่อทดสอบสิ่งนี้ฉันเขียนโค้ดนี้โดยขอยืมมาจากการสอน 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 ***  

18

ข้อแตกต่างที่สำคัญระหว่าง Constructor และngOnInitนั่นngOnInitคือLifecycle Hookและวิ่งตาม Constructor แม่แบบหยันตัวแทนและใส่ค่าเริ่มต้นจะไม่สามารถใช้ได้ในตัวสร้าง ngOnInitแต่พวกเขาอยู่ในที่มีอยู่

ความแตกต่างในทางปฏิบัติคือngOnInitผลกระทบต่อวิธีการจัดโครงสร้างของโค้ดอย่างไร รหัสเริ่มต้นส่วนใหญ่สามารถย้ายไปngOnInit- ตราบใดที่นี้ไม่ได้สร้างเงื่อนไขการแข่งขัน

ตัวสร้าง antipattern

รหัสเริ่มต้นจำนวนมากทำให้วิธีการสร้างยากที่จะขยายอ่านและทดสอบ

สูตรปกติสำหรับการแยกตรรกะการเริ่มต้นจากตัวสร้างคลาสคือการย้ายไปยังวิธีอื่นเช่น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
}

ฉีดพึ่งพา

บทบาทหลักของตัวสร้างคลาสในเชิงมุมคือการฉีดแบบพึ่งพา ตัวสร้างยังใช้สำหรับคำอธิบายประกอบ DI ใน TypeScript การอ้างอิงเกือบทั้งหมดถูกกำหนดเป็นคุณสมบัติให้กับอินสแตนซ์ของคลาส

ค่าเฉลี่ยคอนสตรัคเตอร์ / ไดเรกทีฟไดเร็กต์มีขนาดใหญ่พอเนื่องจากสามารถมีลายเซ็นแบบหลายบรรทัดเนื่องจากการอ้างอิงทำให้การสร้างลอจิกแบบไม่จำเป็นไปยังตัวสร้างคอนสตรัคชันมีส่วนต่อ antipattern

การเริ่มต้นแบบอะซิงโครนัส

ตัวสร้างการเริ่มต้นแบบอะซิงโครนัสสามารถพิจารณา antipattern และมีกลิ่นได้เนื่องจากการสร้างอินสแตนซ์ของคลาสเสร็จสิ้นก่อนรูทีนแบบอะซิงโครนัสทำและสิ่งนี้สามารถสร้างเงื่อนไขการแข่งขันได้ หากไม่ใช่กรณีดังกล่าว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สามารถถูก stubbed ทั้งหมดเพื่อให้แยกสำหรับหน่วยส่วนประกอบอื่น ๆ (เช่นตรรกะบางแม่แบบ)

มรดก

ชั้นเรียนของเด็กสามารถเพิ่ม Constructor เท่านั้นไม่สามารถแทนที่ได้

เนื่องจากthisไม่สามารถอ้างถึงก่อนหน้าsuper()นี้ได้ทำให้มีข้อ จำกัด ในการเริ่มต้น

เมื่อพิจารณาว่าองค์ประกอบเชิงมุมหรือการใช้คำสั่งngOnInitสำหรับตรรกะการกำหนดค่าเริ่มต้นที่ไม่คำนึงถึงเวลาคลาสเด็กสามารถเลือกได้ว่าsuper.ngOnInit()จะเรียกและเมื่อ:

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

สิ่งนี้คงเป็นไปไม่ได้ที่จะนำไปใช้กับคอนสตรัคเตอร์เพียงอย่างเดียว


12

คำตอบข้างต้นไม่ได้ตอบคำถามในแง่มุมดั้งเดิมของคำถามนี้: วงจรชีวิตคืออะไร? ฉันใช้เวลาสักครู่เพื่อทำความเข้าใจความหมายจนกว่าฉันจะคิดแบบนี้

1) องค์ประกอบของคุณเป็นมนุษย์ มนุษย์มีชีวิตที่มีหลายขั้นตอนแล้วเราก็หมดอายุ

2) องค์ประกอบของมนุษย์ของเราสามารถมีวงจรชีวิตสคริปต์ต่อไปนี้: เกิด, เด็ก, โรงเรียนเกรด, ผู้ใหญ่, ผู้ใหญ่วัยกลางคน, ผู้ใหญ่อาวุโส, ตาย, ถูกกำจัด

3) สมมติว่าคุณต้องการมีฟังก์ชั่นในการสร้างลูก เพื่อป้องกันไม่ให้สิ่งนี้มีความซับซ้อนและค่อนข้างตลกขบขันคุณต้องการให้งานของคุณถูกเรียกเฉพาะในช่วงวัยผู้ใหญ่ของชีวิตองค์ประกอบมนุษย์ ดังนั้นคุณจึงพัฒนาส่วนประกอบที่ใช้งานได้ก็ต่อเมื่อองค์ประกอบหลักอยู่ในช่วงวัยผู้ใหญ่ hooks ช่วยให้คุณทำเช่นนั้นได้ด้วยการส่งสัญญาณช่วงเวลาแห่งชีวิตและปล่อยให้องค์ประกอบของคุณทำตาม

สิ่งที่สนุก. ถ้าคุณปล่อยให้จินตนาการของคุณไปเขียนโค้ดแบบนี้มันจะซับซ้อนและตลก


7

ตัวสร้างเป็นวิธีการใน JavaScript และถือเป็นคุณสมบัติของคลาสใน es6 เมื่อชั้นถูกสร้างอินสแตนซ์มันทันทีเรียกใช้ตัวสร้างไม่ว่าจะใช้ในกรอบ Angular หรือไม่ดังนั้นมันถูกเรียกโดยเครื่องมือ JavaScript และ Angular ไม่มี ควบคุมว่า

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) ไม่มีแองกูลาร์)

new CONSTRUCTORTEST();

ด้วยเหตุนี้จึงมีตะขอวงจรชีวิตngOnInitใน Angular.ngOnInit แสดงผลเมื่อ Angular เสร็จสิ้นการเริ่มต้นส่วนประกอบ

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

ก่อนอื่นเราจะยกตัวอย่างคลาสดังต่อไปนี้ซึ่งเกิดขึ้นกับการรันของเมธอด constructor ทันที

let instance = new NGONINITTEST();

ngOnInit ถูกเรียกใช้โดย Angular เมื่อจำเป็นดังต่อไปนี้:

instance.ngOnInit();

แต่คุณอาจถามว่าทำไมเราถึงใช้ตัวสร้างใน Angular

คำตอบคือการพึ่งพาการฉีดตามที่ได้กล่าวไว้ก่อนการเรียก constructor โดยเครื่องมือ JavaScript ทันทีเมื่อคลาสนั้นถูกสร้างอินสแตนซ์ (ก่อนที่จะเรียก ngOnInit โดย Angular) ดังนั้น typescript จะช่วยให้เราได้ชนิดของการพึ่งพาที่กำหนดไว้ในนวกรรมิก ชนิดของการพึ่งพาที่เราต้องการใช้ในองค์ประกอบเฉพาะนั้น


7

สองสิ่งที่ควรสังเกตที่นี่:

  1. ตัวสร้างถูกเรียกเมื่อใดก็ตามที่วัตถุถูกสร้างขึ้นของคลาส
  2. ngOnInit เรียกว่าเมื่อองค์ประกอบถูกสร้างขึ้น

ทั้งสองมีการใช้งานที่แตกต่างกัน


5

นวกรรมิก ()เป็นวิธีการเริ่มต้นในวงจรชีวิตส่วนประกอบและใช้สำหรับการฉีดพึ่งพา ตัวสร้างเป็นคุณสมบัติตัวพิมพ์

ngOnInit ()ถูกเรียกหลังจากตัวสร้างและ ngOnInit ถูกเรียกหลังจาก ngOnChanges แรก

เช่น:

ตัวสร้าง () -->ngOnChanges () -->ngOnInit ()

ตามที่กล่าวไว้ข้างต้นngOnChanges()จะถูกเรียกเมื่อการเปลี่ยนแปลงค่าการเชื่อมโยงอินพุตหรือเอาต์พุต


4

ทั้งสองวิธีมีเป้าหมาย / ความรับผิดชอบแตกต่างกัน งานของตัวสร้าง (ซึ่งเป็นคุณสมบัติที่รองรับภาษา) คือการทำให้แน่ใจว่าการเป็นตัวแทนคงที่ ระบุเป็นอย่างอื่นเพื่อให้แน่ใจว่าอินสแตนซ์นั้นถูกต้องโดยให้ค่าที่ถูกต้องแก่สมาชิก ขึ้นอยู่กับผู้พัฒนาที่จะตัดสินใจว่า 'ถูกต้อง' หมายถึงอะไร

งานของวิธี onInit () (ซึ่งเป็นแนวคิดเชิงมุม) คือการอนุญาตให้มีการเรียกใช้เมธอดบนวัตถุที่ถูกต้อง (การแสดงค่าคงที่) แต่ละวิธีควรตรวจสอบให้แน่ใจว่าค่าคงที่ของการแทนค่าคงอยู่เมื่อเมธอดสิ้นสุดลง

นวกรรมิกควรจะใช้ในการสร้างวัตถุ 'ถูกต้อง' วิธีการ onInit ให้โอกาสในการเรียกวิธีการโทรในอินสแตนซ์ที่กำหนดไว้อย่างดี


4

คอนสตรัค: วิธีการสร้างในคลาส ES6 (หรือ TypeScript ในกรณีนี้) เป็นคุณลักษณะของคลาสเองมากกว่าคุณสมบัติเชิงมุม มันอยู่นอกเหนือการควบคุมของ Angular เมื่อมีการเรียกใช้ตัวสร้างซึ่งหมายความว่าไม่ใช่ตะขอที่เหมาะสมที่จะแจ้งให้คุณทราบเมื่อ Angular ได้เริ่มต้นส่วนประกอบเสร็จสิ้น เอ็นจิ้น JavaScript เรียกใช้ตัวสร้างไม่ใช่แองกูลาร์โดยตรง นี่คือเหตุผลว่าทำไมวงจรชีวิตของ ngOnInit (และ $ onInit in AngularJS) ถูกสร้างขึ้น คำนึงถึงเรื่องนี้ว่ามีสถานการณ์ที่เหมาะสมสำหรับการใช้ตัวสร้าง นี่คือเมื่อเราต้องการที่จะใช้การฉีดพึ่งพา - เป็นหลักสำหรับการพึ่งพา "เดินสาย" ในองค์ประกอบ

ในฐานะที่เป็นตัวสร้างถูกเริ่มต้นโดยเครื่องยนต์ JavaScript และ TypeScript ช่วยให้เราสามารถบอก Angular ว่าการพึ่งพาที่เราต้องการที่จะแมปกับคุณสมบัติที่เฉพาะเจาะจง

ngOnInitนั้นล้วนอยู่ที่นั่นเพื่อส่งสัญญาณให้เราทราบว่า Angular ได้ทำการเริ่มต้นส่วนประกอบเรียบร้อยแล้ว

ขั้นตอนนี้รวมถึงการส่งครั้งแรกที่การตรวจจับการเปลี่ยนแปลงกับคุณสมบัติที่เราอาจผูกกับองค์ประกอบของตัวเอง - เช่นการใช้มัณฑนากร @Input ()

ด้วยเหตุนี้คุณสมบัติ @Input () จึงมีอยู่ใน ngOnInit แต่ไม่ได้กำหนดไว้ภายในตัวสร้างโดยการออกแบบ


2

ตัวสร้างเป็นตัวแรกและบางครั้งมันก็เกิดขึ้นเมื่อข้อมูล @input เป็นโมฆะ! ดังนั้นเราจึงใช้ 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 นั้นเหมือนกับ InitialComponents () ใน winForm


1

ในวงจรชีวิตเชิงมุม

1) หัวฉีดเชิงมุมตรวจจับพารามิเตอร์คอนสตรัคเตอร์ (s) และคลาสอินสแตนซ์

2) วงจรชีวิตการเรียกเชิงมุมถัดไป

ตะขอ Lifecycle เชิงมุม

ngOnChanges -> การโทรในพารามิเตอร์ directive binding

ngOnInit -> เริ่มการเรนเดอร์เชิงมุม ...

เรียกวิธีอื่นด้วยสถานะของวงจรชีวิตเชิงมุม


1

constructorถูกเรียกเมื่อเชิงมุม "instanciates / สร้าง" ส่วนประกอบ ngOnInitวิธีคือเบ็ดซึ่งหมายถึงการเป็นส่วนหนึ่งของการเริ่มต้นของวงจรชีวิตส่วนประกอบ แนวปฏิบัติที่ดีคือใช้สำหรับการฉีดบริการเท่านั้น:

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

แม้ว่าจะเป็นไปได้ แต่คุณไม่ควรทำ "งาน" ข้างใน หากคุณต้องการเปิดใช้การกระทำบางอย่างที่ต้องเกิดขึ้นที่องค์ประกอบ "การเริ่มต้น" ให้ใช้ngOnInit:

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

นอกจากนี้การกระทำที่เกี่ยวข้องกับคุณสมบัติการป้อนข้อมูลที่มาจากองค์ประกอบหลักไม่สามารถทำได้ในตัวสร้าง พวกเขาควรจะอยู่ในngOnInitวิธีการหรือเบ็ดอื่น มันเป็นสิ่งเดียวกันสำหรับองค์ประกอบที่เกี่ยวข้องกับมุมมอง (DOM) ตัวอย่างเช่นองค์ประกอบมุมมองเด็ก :

@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
เห็นด้วยนี่สั้นและชัดเจน ตัวอย่างเช่นนวกรรมิก () สำหรับการเพิ่มวัตถุบริการ ngOnInit () สำหรับการจัดการส่วนประกอบที่มีการเรียกใช้บริการฟังก์ชั่นที่จำเป็น
Steve

0

ฉันพบคำตอบและพยายามแปลเป็นภาษาอังกฤษ: คำถามนี้ยังคงเกิดขึ้นแม้ในการสัมภาษณ์ทางเทคนิค ในความเป็นจริงมีความคล้ายคลึงกันอย่างมากระหว่างทั้งสอง แต่ยังมีความแตกต่างบางอย่าง

  • ตัวสร้างเป็นส่วนหนึ่งของ ECMAScript ในทางกลับกัน ngOnInit () เป็นแนวคิดเกี่ยวกับมุม

  • เราสามารถเรียกใช้ตัวสร้างในคลาสทั้งหมดแม้ว่าเราจะไม่ใช้ Angular

  • LifeCycle: นวกรรมิกถูกเรียกมาก่อน ngOnInt ()

  • ในตัวสร้างเราไม่สามารถเรียกองค์ประกอบ HTML อย่างไรก็ตามใน ngOnInit () เราทำได้

  • โดยทั่วไปแล้วการเรียกใช้บริการใน ngOnInit () และไม่ได้อยู่ในตัวสร้าง

    ที่มา: http://www.angular-tuto.com/Angular/Component#Diff


0

นวกรรมิก

ฟังก์ชั่นคอนสตรัคเตอร์มาพร้อมกับคลาสทุกคลาสคอนสตรัคเตอร์ไม่เฉพาะกับแองกูลาร์ แต่เป็นแนวคิดที่ได้มาจากการออกแบบเชิงวัตถุ ตัวสร้างสร้างอินสแตนซ์ของคลาสองค์ประกอบ

OnInit

ngOnInitฟังก์ชั่นเป็นหนึ่งในวิธีวงจรชีวิตเป็นองค์ประกอบเชิงมุมของ วิธีวงจรชีวิต (หรือ hooks) ในองค์ประกอบเชิงมุมช่วยให้คุณสามารถเรียกใช้ชิ้นส่วนของรหัสในขั้นตอนต่าง ๆ ของชีวิตของส่วนประกอบ ซึ่งแตกต่างจากวิธีการสร้างวิธีngOnInitการมาจากอินเทอร์เฟซแบบ Angular ( OnInit) ที่คอมโพเนนต์ต้องการนำมาใช้เพื่อใช้วิธีนี้ ngOnInitวิธีการที่เรียกว่าไม่นานหลังจากที่องค์ประกอบที่จะถูกสร้างขึ้น


0

ตัวสร้างจะถูกดำเนินการเมื่อชั้นมีการยกตัวอย่าง มันไม่มีอะไรเกี่ยวข้องกับมุม มันเป็นคุณสมบัติของ Javascript และ Angular ไม่สามารถควบคุมมันได้

ngOnInit เป็นแบบ Angular ที่เจาะจงและถูกเรียกเมื่อ Angular ได้เริ่มต้นองค์ประกอบด้วยคุณสมบัติอินพุตทั้งหมด

คุณสมบัติ @Input มีอยู่ภายใต้ตะขอวงจรชีวิต ngOnInit สิ่งนี้จะช่วยให้คุณทำการเริ่มต้นบางอย่างเช่นรับข้อมูลจากเซิร์ฟเวอร์ส่วนหลัง ฯลฯ เพื่อแสดงในมุมมอง

@ คุณสมบัติการป้อนข้อมูลจะแสดงขึ้นเป็นไม่ได้กำหนดไว้ภายในตัวสร้าง


-1

ตัวสร้างเป็นฟังก์ชั่นที่ดำเนินการเมื่อมีการสร้างส่วนประกอบ (หรือคลาสอื่น)

ngOnInitเป็นฟังก์ชั่นที่อยู่ในกลุ่มวิธีวงจรชีวิตขององค์ประกอบและพวกเขาจะถูกดำเนินการในช่วงเวลาที่แตกต่างกันขององค์ประกอบของเรา (นั่นคือเหตุผลที่ชื่อวงจรชีวิต) นี่คือรายการของพวกเขาทั้งหมด:

ป้อนคำอธิบายรูปภาพที่นี่ ตัวสร้างจะถูกดำเนินการก่อนที่จะมีฟังก์ชั่นวงจรชีวิตใด ๆ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.