Angular cung cấp móc vòng đời ngOnInit
theo mặc định.
Tại sao nên ngOnInit
sử dụng, nếu chúng ta đã có một constructor
?
Angular cung cấp móc vòng đời ngOnInit
theo mặc định.
Tại sao nên ngOnInit
sử dụng, nếu chúng ta đã có một constructor
?
Câu trả lời:
Các Constructor
là một phương pháp mặc định của lớp được thực hiện khi lớp được khởi tạo và đảm bảo khởi động đúng đắn của các lĩnh vực trong lớp và lớp con của nó. Angular, hoặc phụ thuộc tốt hơn (DI), phân tích các tham số của hàm tạo và khi nó tạo một thể hiện mới bằng cách gọi new MyClass()
nó cố gắng tìm các nhà cung cấp khớp với các loại tham số của hàm tạo, giải quyết chúng và chuyển chúng đến hàm tạo như
new MyClass(someArg);
ngOnInit
là một cái móc vòng đời được gọi bởi Angular để chỉ ra rằng Angular đã hoàn thành việc tạo ra thành phần.
Chúng tôi phải nhập OnInit
như thế này để sử dụng nó (thực tế việc triển khai OnInit
không bắt buộc nhưng được coi là thực hành tốt):
import { Component, OnInit } from '@angular/core';
sau đó để sử dụng làm cho chúng ta phương thức OnInit
, chúng ta phải thực hiện lớp như thế này:
export class App implements OnInit {
constructor() {
// Called first time before the ngOnInit()
}
ngOnInit() {
// Called after the constructor and called after the first ngOnChanges()
}
}
Triển khai giao diện này để thực thi logic khởi tạo tùy chỉnh sau khi các thuộc tính ràng buộc dữ liệu của lệnh của bạn đã được khởi tạo. ngOnInit được gọi ngay sau khi các thuộc tính ràng buộc dữ liệu của lệnh được kiểm tra lần đầu tiên và trước khi bất kỳ con nào của nó được kiểm tra. Nó chỉ được gọi một lần khi lệnh được khởi tạo.
Chủ yếu chúng tôi sử dụng ngOnInit
cho tất cả các khởi tạo / khai báo và tránh các công cụ để làm việc trong hàm tạo. Hàm tạo chỉ nên được sử dụng để khởi tạo các thành viên lớp nhưng không nên thực hiện "công việc" thực tế.
Vì vậy, bạn nên sử dụng constructor()
để thiết lập Dependency Injection và không nhiều thứ khác. ngOnInit () là nơi tốt hơn để "bắt đầu" - đó là nơi / khi các ràng buộc của các thành phần được giải quyết.
Để biết thêm thông tin tham khảo tại đây:
tsconfig.json
tệp như thế "strict": true
, thì bạn phải khởi tạo các thành viên lớp trong constructor
, chứ không phải ngOnit
như thế FormGroup
.
Bài viết Sự khác biệt cơ bản giữa Người xây dựng và ngOnInit trong Angular khám phá sự khác biệt từ nhiều quan điểm. Câu trả lời này cung cấp giải thích khác biệt quan trọng nhất liên quan đến quá trình khởi tạo thành phần cũng cho thấy sự khác biệt trong cách sử dụng.
Quá trình bootstrap góc bao gồm hai giai đoạn chính:
Hàm tạo của thành phần được gọi khi Angular xây dựng cây thành phần. Tất cả các móc vòng đời được gọi là một phần của việc phát hiện thay đổi đang chạy.
Khi Angular xây dựng các thành phần cây, bộ tiêm mô-đun gốc đã được cấu hình để bạn có thể tiêm bất kỳ phụ thuộc toàn cục nào. Ngoài ra, khi Angular khởi tạo một lớp thành phần con, trình tiêm cho thành phần cha mẹ cũng đã được thiết lập để bạn có thể tiêm các nhà cung cấp được xác định trên thành phần cha mẹ bao gồm chính thành phần cha mẹ. Các hàm tạo thành phần là phương thức duy nhất được gọi trong ngữ cảnh của trình tiêm, vì vậy nếu bạn cần bất kỳ sự phụ thuộc nào thì đó là nơi duy nhất có được các phụ thuộc đó.
Khi Angular bắt đầu phát hiện thay đổi, cây thành phần được xây dựng và các hàm tạo cho tất cả các thành phần trong cây đã được gọi. Ngoài ra, các nút mẫu của mọi thành phần được thêm vào DOM. Cơ @Input
chế giao tiếp được xử lý trong quá trình phát hiện thay đổi, do đó bạn không thể mong đợi có các thuộc tính có sẵn trong hàm tạo. Nó sẽ có sẵn sau ngOnInit
.
Hãy xem một ví dụ nhanh. Giả sử bạn có mẫu sau:
<my-app>
<child-comp [i]='prop'>
Vì vậy, Angular bắt đầu bootstrapping ứng dụng. Như tôi đã nói, đầu tiên nó tạo các lớp cho mỗi thành phần. Vì vậy, nó gọi MyAppComponent
constructor. Nó cũng tạo ra một nút DOM là thành phần chủ của my-app
thành phần. Sau đó, nó tiến hành tạo một phần tử máy chủ cho hàm tạo child-comp
và gọi hàm ChildComponent
tạo. Ở giai đoạn này, nó không thực sự liên quan đến i
ràng buộc đầu vào và bất kỳ móc vòng đời nào. Vì vậy, khi quá trình này kết thúc, Angular kết thúc với các khung nhìn thành phần sau:
MyAppView
- MyApp component instance
- my-app host element data
ChildCompnentView
- ChildComponent component instance
- child-comp host element data
Chỉ sau đó chạy phát hiện thay đổi và cập nhật các ràng buộc cho my-app
và các cuộc gọi ngOnInit
trên lớp MyAppComponent. Sau đó, nó tiến hành cập nhật các ràng buộc cho child-comp
và gọi ngOnInit
trên lớp ChildComponent.
Bạn có thể thực hiện logic khởi tạo của mình trong hàm tạo hoặc ngOnInit
tùy thuộc vào những gì bạn cần có sẵn. Ví dụ bài viết Dưới đây là cách lấy ViewContainerRef trước khi truy vấn @ViewChild được đánh giá cho thấy loại logic khởi tạo nào có thể được yêu cầu để được thực hiện trong hàm tạo.
Dưới đây là một số bài viết sẽ giúp bạn hiểu rõ hơn về chủ đề:
the constructor should only be used to inject dependencies
.
Tôi nghĩ rằng ví dụ tốt nhất sẽ được sử dụng dịch vụ. Giả sử tôi muốn lấy dữ liệu từ máy chủ của mình khi thành phần của tôi được 'Kích hoạt'. Giả sử tôi cũng muốn thực hiện một số điều bổ sung cho dữ liệu sau khi tôi nhận được nó từ máy chủ, có thể tôi gặp lỗi và muốn đăng nhập dữ liệu khác.
Nó thực sự dễ dàng với ngOnInit qua một hàm tạo, nó cũng giới hạn số lượng lớp gọi lại mà tôi cần thêm vào ứng dụng của mình.
Ví dụ:
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);
};
}
với hàm tạo của tôi, tôi chỉ có thể gọi _userService của mình và điền vào user_list của mình, nhưng có lẽ tôi muốn làm thêm một số thứ với nó. Giống như đảm bảo mọi thứ đều là chữ hoa, tôi không hoàn toàn chắc chắn làm thế nào dữ liệu của tôi được thông qua.
Vì vậy, nó làm cho nó dễ dàng hơn nhiều để sử dụng 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();
};
}
Nó làm cho nó dễ nhìn hơn nhiều, và vì vậy tôi chỉ gọi hàm của mình trong thành phần của mình khi tôi khởi tạo thay vì phải đào nó ở một nơi khác. Thực sự nó chỉ là một công cụ khác mà bạn có thể sử dụng để giúp đọc và sử dụng dễ dàng hơn trong tương lai. Ngoài ra tôi thấy thực tế rất tệ khi đặt các lệnh gọi hàm trong hàm tạo!
getUsers
và sau đó chèn nó vào ngOnInit
? Có phải nó không ít mã để chỉ viết nó trong ngOnInit? Tôi là jsut tự hỏi tại sao mọi người làm theo cách này? Có phải vì vậy mà bạn có thể sử dụng lại mã nếu bạn cũng muốn? Cảm ơn.
constructor
?
constructor(private _userService: UserService){ this.getUsers(); };
OK, trước hết ngOnInit
là một phần của vòng đời Angular , trong khi constructor
là một phần của lớp JavaScript ES6 , vì vậy sự khác biệt chính bắt đầu từ ngay tại đây! ...
Nhìn vào biểu đồ dưới đây tôi tạo ra cho thấy vòng đời của Angular.
Trong Angular2 +, chúng tôi sử dụng constructor
để làm điều đó DI(Dependency Injection)
cho chúng tôi, trong khi ở Angular 1, điều đó đã xảy ra thông qua việc gọi phương thức String và kiểm tra xem sự phụ thuộc nào đã được đưa vào.
Như bạn thấy trong sơ đồ trên, ngOnInit
sẽ xảy ra sau khi hàm tạo sẵn sàng ngOnChnages
và được kích hoạt sau khi thành phần sẵn sàng cho chúng ta. Tất cả các khởi tạo có thể xảy ra trong giai đoạn này, một mẫu đơn giản là tiêm dịch vụ và khởi tạo nó trên init.
OK, tôi cũng chia sẻ một mã mẫu để bạn xem, xem cách chúng tôi sử dụng ngOnInit
và constructor
trong mã dưới đây:
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!');
}
}
Cái đầu tiên (constructor) có liên quan đến khởi tạo lớp và không liên quan gì đến Angular2. Tôi có nghĩa là một constructor có thể được sử dụng trên bất kỳ lớp nào. Bạn có thể đặt vào đó một số xử lý khởi tạo cho thể hiện mới được tạo.
Cái thứ hai tương ứng với móc vòng đời của các thành phần Angular2:
Trích dẫn từ trang web chính thức của angular:
ngOnChanges
được gọi khi giá trị ràng buộc đầu vào hoặc đầu ra thay đổingOnInit
được gọi sau đầu tiênngOnChanges
Vì vậy, bạn nên sử dụng ngOnInit
nếu quá trình khởi tạo phụ thuộc vào các ràng buộc của thành phần (ví dụ: các tham số thành phần được xác định @Input
), nếu không thì hàm tạo sẽ đủ ...
Tôi sẽ chỉ thêm một điều quan trọng đã bị bỏ qua trong các giải thích ở trên và giải thích khi bạn PHẢI sử dụng ngOnInit
.
Nếu bạn đang thực hiện bất kỳ thao tác nào của DOM của thành phần thông qua ví dụ ViewChildren , ContentChildren hoặc ElementRef , các phần tử nguyên gốc của bạn sẽ không khả dụng trong giai đoạn xây dựng.
Tuy nhiên, kể từ khi ngOnInit
xảy ra một khi thành phần đã được tạo và kiểm tra ( ngOnChanges
) đã được gọi, bạn có thể truy cập DOM tại thời điểm này.
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
}
}
@ViewChildren
cụ thể, bạn cần sử dụng ngAfterViewInit
phương pháp. Xem tại đây: stackoverflow.com/questions/46314734/
Câu trả lời ngắn gọn và đơn giản sẽ là,
Constructor
: constructor
là một default method
lần chạy ( bởi điếc ) khi thành phần đang được xây dựng. Khi bạn tạo ra an instance
một lớp thời gian cũng constructor(default method)
sẽ được gọi. Vì vậy, nói cách khác, khi thành phần đang được constructed or/and an instance is created constructor(default method)
gọi và mã có liên quan được viết bên trong được gọi. Về cơ bản và nói chung trong Angular2
nó được sử dụng để tiêm những thứ như services
khi thành phần đang được xây dựng để sử dụng tiếp.
OnInit
: ngOnInit là hook vòng đời của thành phần chạy trước sau constructor(default method)
khi thành phần được khởi tạo.
Vì vậy, constructor của bạn sẽ được gọi trước và Oninit sẽ được gọi sau sau phương thức constructor.
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()
}
}
Tài nguyên: Móc vòng đời
Bạn có thể kiểm tra bản demo nhỏ này cho thấy việc thực hiện cả hai điều.
new MyClass()
được thực thi. Tôi nghĩ thật sai lầm khi nói các nhà xây dựng là về các thành phần, chúng là về các lớp và khởi tạo các thể hiện của các lớp này. Một thành phần chỉ là một lớp như vậy. Nếu không, tôi nghĩ rằng đó là một câu trả lời tốt.
constructor
sẽ được gọi. Nhưng câu trả lời này đã được viết trong bối cảnh angular2. Để biết câu trả lời tốt nhất, bạn phải biết những điều cơ bản về OOP. Tôi vẫn sẽ cập nhật câu trả lời.
Giống như nhiều ngôn ngữ khác, bạn có thể khởi tạo các biến ở cấp độ lớp, hàm tạo hoặc một phương thức. Tùy thuộc vào nhà phát triển để quyết định điều gì là tốt nhất trong trường hợp cụ thể của họ. Nhưng dưới đây là danh sách các thực hành tốt nhất khi quyết định.
Thông thường, bạn sẽ khai báo tất cả các biến của bạn ở đây sẽ được sử dụng trong phần còn lại của thành phần. Bạn có thể khởi tạo chúng nếu giá trị không phụ thuộc vào bất cứ điều gì khác hoặc sử dụng từ khóa const để tạo hằng nếu chúng không thay đổi.
export class TestClass{
let varA: string = "hello";
}
Thông thường, cách tốt nhất là không làm gì trong hàm tạo và chỉ sử dụng nó cho các lớp sẽ được thêm vào. Hầu hết thời gian nhà xây dựng của bạn sẽ trông như thế này:
constructor(private http: Http, private customService: CustomService) {}
điều này sẽ tự động tạo các biến cấp độ lớp, vì vậy bạn sẽ có quyền truy cập customService.myMethod()
mà không cần phải thực hiện thủ công.
NgOnit là một cái móc vòng đời được cung cấp bởi khung Angular 2. Thành phần của bạn phải thực hiện OnInit
để sử dụng nó. Móc vòng đời này được gọi sau khi hàm tạo được gọi và tất cả các biến được khởi tạo. Phần lớn việc khởi tạo của bạn nên vào đây. Bạn sẽ chắc chắn rằng Angular đã khởi tạo chính xác thành phần của bạn và bạn có thể bắt đầu thực hiện bất kỳ logic nào bạn cần OnInit
so với thực hiện khi thành phần của bạn chưa tải xong.
Dưới đây là hình ảnh chi tiết thứ tự của cái được gọi là:
https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html
Nếu bạn đang sử dụng khung Angular 2 và cần tương tác với các sự kiện vòng đời nhất định, hãy sử dụng các phương thức được cung cấp bởi khung này để tránh các vấn đề.
Để kiểm tra điều này, tôi đã viết mã này, mượn từ Hướng dẫn NativeScript :
người dùng
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;
}
}
Bảng điều khiển đầu ra
JS: *** User class constructor property ***
JS: *** User class constructor constructor ***
JS: *** Login Component Constructor ***
JS: *** User class constructor ngOnInit ***
JS: *** Login Component ngOnInit ***
Sự khác biệt chính giữa constructor và ngOnInit
đó ngOnInit
là hook vòng đời và chạy sau constructor. Mẫu nội suy thành phần và các giá trị ban đầu đầu vào không có sẵn trong hàm tạo, nhưng chúng có sẵn trong ngOnInit
.
Sự khác biệt thực tế là cách ngOnInit
ảnh hưởng đến cách cấu trúc mã. Hầu hết các mã khởi tạo có thể được chuyển đến ngOnInit
- miễn là điều này không tạo ra điều kiện cuộc đua .
Một lượng đáng kể mã khởi tạo làm cho phương thức constructor khó mở rộng, đọc và kiểm tra.
Một công thức thông thường để tách logic khởi tạo khỏi hàm tạo của lớp là chuyển nó sang một phương thức khác như init
:
class Some {
constructor() {
this.init();
}
init() {...}
}
ngOnInit
có thể phục vụ mục đích này trong các thành phần và chỉ thị:
constructor(
public foo: Foo,
/* verbose list of dependencies */
) {
// time-sensitive initialization code
this.bar = foo.getBar();
}
ngOnInit() {
// rest of initialization code
}
Vai trò chính của các nhà xây dựng lớp trong Angular là tiêm phụ thuộc. Các hàm tạo cũng được sử dụng cho chú thích DI trong TypeScript. Hầu như tất cả các phụ thuộc được gán làm thuộc tính cho thể hiện của lớp.
Trình xây dựng thành phần / chỉ thị trung bình đã đủ lớn bởi vì nó có thể có chữ ký đa dòng do phụ thuộc, đưa logic nội tâm hóa không cần thiết vào phần thân của trình tạo đóng góp vào antipotype.
Hàm tạo khởi tạo không đồng bộ thường có thể được coi là antipotype và có mùi vì quá trình khởi tạo lớp kết thúc trước khi thói quen không đồng bộ thực hiện và điều này có thể tạo ra các điều kiện chạy đua. Nếu không phải như vậy ngOnInit
và các móc vòng đời khác là nơi tốt hơn cho việc này, đặc biệt vì chúng có thể được hưởng lợi từ async
cú pháp:
constructor(
public foo: Foo,
public errorHandler: ErrorHandler
) {}
async ngOnInit() {
try {
await this.foo.getBar();
await this.foo.getBazThatDependsOnBar();
} catch (err) {
this.errorHandler.handleError(err);
}
}
Nếu có các điều kiện chủng tộc (bao gồm cả điều kiện mà một thành phần không nên xuất hiện trong lỗi khởi tạo), thì thói quen khởi tạo không đồng bộ sẽ diễn ra trước khi khởi tạo thành phần và được chuyển sang thành phần chính, bộ bảo vệ bộ định tuyến, v.v.
ngOnInit
linh hoạt hơn một nhà xây dựng và cung cấp một số lợi ích cho thử nghiệm đơn vị được giải thích chi tiết trong câu trả lời này .
Xem xét việc ngOnInit
không được gọi tự động khi biên dịch thành phần trong các thử nghiệm đơn vị, các phương thức được gọi trong ngOnInit
có thể bị theo dõi hoặc chế giễu sau khi khởi tạo thành phần.
Trong các trường hợp đặc biệt ngOnInit
có thể được đặt hoàn toàn để cung cấp sự cô lập cho các đơn vị thành phần khác (ví dụ, một số logic mẫu).
Các lớp con chỉ có thể tăng cường các nhà xây dựng, không thể thay thế chúng.
Vì this
không thể được giới thiệu trước super()
, điều này đặt ra các hạn chế về ưu tiên khởi tạo.
Xem xét rằng thành phần hoặc chỉ thị Angular sử dụng ngOnInit
cho logic khởi tạo không nhạy cảm theo thời gian, các lớp con có thể chọn có super.ngOnInit()
được gọi hay không và khi nào:
ngOnInit() {
this.someMethod();
super.ngOnInit();
}
Điều này sẽ không thể thực hiện với chỉ riêng nhà xây dựng.
Các câu trả lời trên không thực sự trả lời khía cạnh này của câu hỏi ban đầu: móc vòng đời là gì? Phải mất một thời gian tôi mới hiểu điều đó có nghĩa là gì cho đến khi tôi nghĩ về nó theo cách này.
1) Nói thành phần của bạn là một con người. Con người có cuộc sống bao gồm nhiều giai đoạn sống, và sau đó chúng ta hết hạn.
2) Thành phần con người của chúng ta có thể có kịch bản vòng đời sau: Sinh ra, Em bé, Lớp học, Người trưởng thành trẻ tuổi, Người trung niên, Người cao tuổi, Người chết, Bị vứt bỏ.
3) Nói rằng bạn muốn có một chức năng để tạo ra trẻ em. Để giữ cho điều này không trở nên phức tạp và khá hài hước, bạn muốn chức năng của mình chỉ được gọi trong giai đoạn Người trưởng thành trẻ của cuộc sống thành phần con người. Vì vậy, bạn phát triển một thành phần chỉ hoạt động khi thành phần cha mẹ ở giai đoạn Người trưởng thành trẻ tuổi. Móc giúp bạn làm điều đó bằng cách báo hiệu giai đoạn của cuộc sống và để cho thành phần của bạn hành động trên nó.
Công cụ thú vị. Nếu bạn để trí tưởng tượng của mình thực sự mã hóa thứ gì đó như thế này thì nó sẽ trở nên phức tạp và buồn cười.
Hàm tạo là một phương thức trong JavaScript và được coi là một tính năng của lớp trong es6. Khi lớp được khởi tạo, nó ngay lập tức chạy hàm tạo cho dù nó có được sử dụng trong khung Angular hay không. Vì vậy, nó được gọi bởi công cụ JavaScript và Angular không có kiểm soát điều đó
import {Component} from '@angular/core';
@Component({})
class CONSTRUCTORTEST {
//This is called by Javascript not the Angular.
constructor(){
console.log("view constructor initialised");
}
}
Lớp "Con constructorTest" được khởi tạo bên dưới; Vì vậy, bên trong nó gọi hàm tạo (Tất cả những điều này xảy ra bởi JavaScript (es6) no Angular).
new CONSTRUCTORTEST();
Đó là lý do tại sao có ngOnInit vòng đời móc trong Angular.ngOnInit renders khi góc đã hoàn tất initialising các thành phần.
import {Component} from '@angular/core';
@Component({})
class NGONINITTEST implements onInit{
constructor(){}
//ngOnInit calls by Angular
ngOnInit(){
console.log("Testing ngOnInit");
}
}
Đầu tiên chúng ta khởi tạo lớp như bên dưới, điều này xảy ra ngay lập tức khi chạy phương thức constructor.
let instance = new NGONINITTEST();
ngOnInit được gọi bởi Angular khi cần thiết như dưới đây:
instance.ngOnInit();
Nhưng bạn có thể hỏi tại sao chúng ta sử dụng constructor trong Angular?
Câu trả lời là tiêm phụ thuộc . Vì nó đã được đề cập trước đó, hàm tạo được gọi bởi công cụ JavaScript ngay lập tức khi lớp được khởi tạo (trước khi gọi ngOnInit bởi Angular), do đó, typcript giúp chúng ta có được loại phụ thuộc được xác định trong hàm tạo và cuối cùng cho biết Angular loại phụ thuộc mà chúng ta muốn sử dụng trong thành phần cụ thể đó.
constructor () là phương thức mặc định trong vòng đời Thành phần và được sử dụng để tiêm phụ thuộc. Trình xây dựng là một tính năng bản in.
ngOnInit () được gọi sau hàm tạo và ngOnInit được gọi sau ngOnChanges đầu tiên.
I E:
Trình xây dựng () -->ngOnChanges () -->ngOnInit ()
như đã đề cập ở trên ngOnChanges()
được gọi khi giá trị ràng buộc đầu vào hoặc đầu ra thay đổi.
Cả hai phương pháp đều có mục tiêu / trách nhiệm khác nhau. Nhiệm vụ của hàm tạo (là một tính năng được hỗ trợ bằng ngôn ngữ) là đảm bảo rằng bất biến đại diện giữ. Mặt khác được nêu để đảm bảo rằng cá thể hợp lệ bằng cách đưa ra các giá trị chính xác cho các thành viên. Nhà phát triển phải quyết định 'chính xác' nghĩa là gì.
Nhiệm vụ của phương thức onInit () (là một khái niệm góc) là cho phép các yêu cầu phương thức trên một đối tượng chính xác (biểu diễn bất biến). Mỗi phương thức nên lần lượt đảm bảo rằng bất biến đại diện giữ khi phương thức kết thúc.
Hàm tạo nên được sử dụng để tạo các đối tượng 'chính xác', phương thức onInit cung cấp cho bạn cơ hội để gọi các cuộc gọi phương thức trong một trường hợp được xác định rõ.
Trình xây dựng: Phương thức hàm tạo trên lớp ES6 (hoặc TypeScript trong trường hợp này) là một tính năng của chính lớp đó, chứ không phải là một tính năng Angular. Nó nằm ngoài tầm kiểm soát của Angular khi hàm tạo được gọi, điều đó có nghĩa là nó không phải là một hook phù hợp để cho bạn biết khi nào Angular hoàn thành việc khởi tạo thành phần. Công cụ JavaScript gọi hàm tạo, không phải Angular trực tiếp. Đó là lý do tại sao móc vòng đời ngOnInit (và $ onInit trong AngularJS) được tạo ra. Ghi nhớ điều này, có một kịch bản phù hợp để sử dụng hàm tạo. Đây là khi chúng tôi muốn sử dụng phép nội xạ phụ thuộc - về cơ bản cho việc kết nối các phần phụ thuộc vào các thành phần.
Vì hàm tạo được khởi tạo bởi công cụ JavaScript và TypeScript cho phép chúng ta nói với Angular những phụ thuộc mà chúng ta yêu cầu để được ánh xạ với một thuộc tính cụ thể.
ngOnInit hoàn toàn ở đó để cho chúng ta một tín hiệu rằng Angular đã hoàn thành việc khởi tạo thành phần.
Giai đoạn này bao gồm đường chuyền đầu tiên tại Phát hiện thay đổi đối với các thuộc tính mà chúng ta có thể liên kết với chính thành phần đó - chẳng hạn như sử dụng trình trang trí @Input ().
Do đó, các thuộc tính @Input () có sẵn bên trong ngOnInit, tuy nhiên không được xác định bên trong hàm tạo, theo thiết kế
Trình xây dựng là lần đầu tiên và đôi khi nó xảy ra khi dữ liệu @input là null! vì vậy chúng tôi sử dụng Trình xây dựng để khai báo các dịch vụ và ngOnInit xảy ra sau đó. Ví dụ cho contrutor:
constructor(translate: TranslateService, private oauthService: OAuthService) {
translate.setDefaultLang('En');
translate.use('En');}
Ví dụ cho onInit:
ngOnInit() {
this.items = [
{ label: 'A', icon: 'fa fa-home', routerLink: ['/'] },
{ label: 'B', icon: 'fa fa-home', routerLink: ['/'] }]
}
Tôi nghĩ rằng onInit giống như InitialComponents () trong winForm.
Trong vòng đời Angular
1) Tham số hàm tạo góc phát hiện ('s) và lớp khởi tạo.
2) Vòng đời gọi tiếp theo
ngOnChanges -> Gọi ràng buộc tham số chỉ thị.
ngOnInit -> Bắt đầu kết xuất góc ...
Gọi phương pháp khác với trạng thái của vòng đời góc.
Nó constructor
được gọi khi Angular "instanciates / constructs" thành phần. Các ngOnInit
phương pháp là một cái móc mà đại diện cho phần khởi tạo của vòng đời phần. Một thực hành tốt là chỉ sử dụng nó để tiêm dịch vụ :
constructor(private
service1: Service1,
service2: Service2
){};
Ngay cả khi có thể, bạn cũng không nên thực hiện một số "công việc" bên trong. Nếu bạn muốn khởi chạy một số hành động phải xảy ra ở phần "khởi tạo" thành phần, hãy sử dụng ngOnInit
:
ngOnInit(){
service1.someWork();
};
Hơn nữa, các hành động liên quan đến các thuộc tính đầu vào , đến từ thành phần cha mẹ, không thể được thực hiện trong bộ điều khiển. Chúng nên được đặt trong ngOnInit
phương thức hoặc một cái móc khác. Tương tự đối với phần tử liên quan đến chế độ xem (DOM), ví dụ, các phần tử khung nhìn :
@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
};
constructor()
được sử dụng để làm tiêm phụ thuộc.
ngOnInit()
, ngOnChanges()
Và ngOnDestroy()
vv là phương pháp vòng đời. ngOnChanges()
sẽ là người đầu tiên được gọi, trước đó ngOnInit()
, khi giá trị của một thuộc tính ràng buộc thay đổi, nó sẽ KHÔNG được gọi nếu không có thay đổi. ngOnDestroy()
được gọi khi thành phần bị loại bỏ. Để sử dụng nó, OnDestroy
cần phải được implement
ed bởi lớp.
Tôi đã tìm thấy câu trả lời và tôi đã cố dịch nó sang tiếng Anh: Câu hỏi này vẫn phát sinh, ngay cả trong các cuộc phỏng vấn kỹ thuật. Trong thực tế, có một sự tương đồng lớn giữa hai người, nhưng cũng có một số khác biệt.
Hàm tạo là một phần của ECMAScript. Mặt khác ngOnInit () là một khái niệm về góc.
Chúng ta có thể gọi các hàm tạo trong tất cả các lớp ngay cả khi chúng ta không sử dụng Angular
Vòng đời: Hàm tạo được gọi trước ngOnInt ()
Trong hàm tạo, chúng ta không thể gọi các phần tử HTML. Tuy nhiên, trong ngOnInit () chúng ta có thể.
Nói chung, các cuộc gọi của dịch vụ trong ngOnInit () chứ không phải trong hàm tạo
Constructor
Hàm constructor đi kèm với mọi lớp, các constructor không đặc trưng cho Angular nhưng là các khái niệm xuất phát từ các thiết kế hướng đối tượng. Hàm tạo tạo một thể hiện của lớp thành phần.
OnInit
Các ngOnInit
chức năng là một trong những phương pháp vòng đời một thành phần góc của. Các phương thức vòng đời (hoặc móc) trong các thành phần Angular cho phép bạn chạy một đoạn mã ở các giai đoạn khác nhau trong vòng đời của một thành phần. Không giống như phương thức constructor, ngOnInit
phương thức xuất phát từ giao diện Angular ( OnInit
) mà thành phần cần triển khai để sử dụng phương thức này. Các ngOnInit
phương pháp được gọi là một thời gian ngắn sau khi thành phần được tạo ra.
Trình xây dựng được thực thi khi lớp được khởi tạo. Nó không có gì để làm với các góc. Đây là tính năng của Javascript và Angular không có quyền kiểm soát nó
NgOnInit là đặc trưng của Angular và được gọi khi Angular đã khởi tạo thành phần với tất cả các thuộc tính đầu vào của nó
Các thuộc tính @Input có sẵn trong móc vòng đời ngOnInit. Điều này sẽ giúp bạn thực hiện một số công cụ khởi tạo như lấy dữ liệu từ máy chủ phụ, v.v. để hiển thị trong chế độ xem
Các thuộc tính @Input được hiển thị là không xác định bên trong hàm tạo
Hàm xây dựng là một hàm được thực thi khi thành phần (hoặc lớp khác) được xây dựng.
ngOnInit là một hàm thuộc các nhóm phương thức vòng đời thành phần và chúng được thực thi trong một thời điểm khác nhau của thành phần của chúng tôi (đó là lý do tại sao đặt tên cho vòng đời). Dưới đây là danh sách tất cả chúng:
Trình xây dựng sẽ được thực thi trước bất kỳ chức năng vòng đời nào.