Угловая ngOnInit
обеспечивает цикл жизненного цикла ngOnInit
по умолчанию.
Зачем использовать ngOnInit
, если у нас уже есть constructor
?
Угловая ngOnInit
обеспечивает цикл жизненного цикла ngOnInit
по умолчанию.
Зачем использовать ngOnInit
, если у нас уже есть constructor
?
Constructor
- это метод по умолчанию класса, который выполняется при создании экземпляра класса и обеспечивает правильную инициализацию полей в классе и его подклассах. Угловой или более эффективный инжектор зависимостей (DI) анализирует параметры конструктора, и когда он создает новый экземпляр, вызывая new MyClass()
он пытается найти поставщиков, которые соответствуют типам параметров конструктора, решает их и передает их конструктору, например
new MyClass(someArg);
ngOnInit
- это крючок жизненного цикла, называемый Angular2, чтобы указать, что 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()
для настройки Injection Dependency и не более того. ngOnInit() - лучшее место для "запуска" - там, где/когда привязки компонентов разрешены.
Для получения дополнительной информации см. Здесь:
Статья Существенное различие между конструктором и ngOnInit в Angular раскрывает разницу с несколькими перспективами. Этот ответ дает наиболее важное объяснение разницы, связанное с процессом инициализации компонента, которое также показывает разные значения использования.
Angular Процесс начальной загрузки состоит из двух основных этапов:
Конструктор компонента вызывается, когда Angular строит дерево компонентов. Все крючки жизненного цикла называются как часть запуска обнаружения изменений.
Когда Angular создает дерево компонентов, инжектор корневого модуля уже настроен, поэтому вы можете вводить любые глобальные зависимости. Кроме того, когда Angular создает экземпляр класса дочерних компонентов, инжектор для родительского компонента также уже настроен, поэтому вы можете вводить провайдеры, определенные на родительском компоненте, включая сам родительский компонент. Конструкторы компонентов - это единственный метод, который вызывается в контексте инжектора, поэтому, если вам нужна какая-либо зависимость, единственное место для получения этих зависимостей.
Когда Angular начинает обнаружение изменений, создается дерево компонентов и вызываются конструкторы для всех компонентов в дереве. Также каждый узел шаблона компонента добавляется в DOM. Механизм связи @Input
обрабатывается во время обнаружения изменений, поэтому вы не можете ожидать наличия свойств в конструкторе. Он будет доступен после ngOnInit
.
Посмотрим на быстрый пример. Предположим, у вас есть следующий шаблон:
<my-app>
<child-comp [i]='prop'>
Итак, Angular запускает загрузку приложения. Как я уже сказал, он сначала создает классы для каждого компонента. Поэтому он вызывает конструктор MyAppComponent
. Он также создает DOM node, который является элементом хоста компонента 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 показывает, какой тип логики инициализации может потребоваться выполнить в конструкторе.
Вот несколько статей, которые помогут вам лучше понять тему:
Думаю, лучшим примером будет использование сервисов. Скажем, что я хочу захватить данные с моего сервера, когда мой компонент получает "Активирован". Скажем, что я также хочу сделать некоторые дополнительные вещи для данных после того, как я получу их с сервера, возможно, я получаю сообщение об ошибке и хочу, чтобы он записывался по-разному.
Это действительно легко с 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();
};
}
Это намного облегчает просмотр, и поэтому я просто вызываю свою функцию внутри своего компонента, когда я инициализирую вместо того, чтобы копать в другом месте. На самом деле это еще один инструмент, который вы можете использовать для упрощения чтения и использования в будущем. Также я нахожу, что очень плохая практика - вызывать вызовы функций внутри конструктора!
ОК, прежде всего, ngOnInit
является частью цикла Углового цикла, а constructor
является частью класса JavaScript ES6, поэтому основное различие начинается прямо здесь!...
Посмотрите на приведенную ниже диаграмму, которая показывает жизненный цикл Angular.
В 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!');
}
}
Первый (конструктор) связан с экземпляром класса и не имеет ничего общего с Angular2. Я имею в виду, что конструктор может использоваться для любого класса. Вы можете добавить в него некоторую обработку инициализации для вновь созданного экземпляра.
Второй соответствует крюку жизненного цикла компонентов Angular2:
Цитата из официального angular сайта:
ngOnChanges
вызывается, когда значение привязки ввода или вывода изменяетсяngOnInit
вызывается после первогоngOnChanges
Итак, вы должны использовать ngOnInit
, если обработка инициализации зависит от привязок компонента (например, параметров компонента, определенных с помощью @Input
), в противном случае конструктора будет достаточно...
Я просто добавлю одну важную вещь, которая была пропущена в объяснениях выше и объясняет, когда вы ДОЛЖНЫ использовать ngOnInit
.
Если вы выполняете какие-либо манипуляции с компонентом DOM, например, с помощью ViewChildren, ContentChildren или ElementRef, ваши собственные элементы не будут доступны на этапе конструктора.
Однако, поскольку ngOnInit
происходит после того, как компонент был создан и ngOnChanges
проверки (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
}
}
Короткий и простой ответ был бы,
Constructor
: Constructor
- это пробег 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
Вы можете проверить эту небольшую демонстрацию, которая показывает реализацию обеих вещей.
Чтобы проверить это, я написал этот код, заимствуя из 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 ***
Как и многие другие языки, вы можете инициализировать переменные на уровне класса, конструкторе или методе. Разработчик должен решить, что лучше в их конкретном случае. Но ниже приведен список лучших практик, когда дело доходит до принятия решения.
Обычно вы объявляете все свои переменные здесь, которые будут использоваться в остальном компоненте. Вы можете инициализировать их, если значение не зависит от чего-либо еще, или используйте ключевое слово const для создания констант, если они не будут изменены.
export class TestClass{
let varA: string = "hello";
}
Обычно лучше всего ничего не делать в конструкторе и просто использовать его для классов, которые будут введены. В большинстве случаев ваш конструктор должен выглядеть следующим образом:
constructor(private http: Http, private customService: CustomService) {}
это автоматически создаст переменные уровня класса, поэтому у вас будет доступ к customService.myMethod()
без необходимости делать это вручную.
NgOnit - это крючок жизненного цикла, предоставляемый каркасом Angular 2. Ваш компонент должен реализовать OnInit
, чтобы использовать его. Этот крючок жизненного цикла вызывается после вызова конструктора и инициализации всех переменных. Основная часть вашей инициализации должна идти здесь. У вас будет определенность, что Angular правильно инициализирует ваш компонент, и вы можете начать делать любую логику, которая вам нужна в OnInit
, и делать то, что ваш компонент не закончил правильно загружать.
Вот изображение, детализирующее порядок вызова:
https://angular.io/docs/ts/latest/guide/lifecycle-hooks.html
Если вы используете фреймворк Angular 2 и должны взаимодействовать с определенными событиями жизненного цикла, используйте методы, предоставленные инфраструктурой, чтобы избежать проблем.
Основное различие между конструктором и ngOnInit
состоит в том, что ngOnInit
является ngOnInit
жизненного цикла и выполняется после конструктора. Шаблон интерполированного компонента и входные начальные значения недоступны в конструкторе, но они доступны в 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 - внедрение зависимостей. Конструкторы также используются для аннотации DI в TypeScript. Почти все зависимости присваиваются как свойства экземпляру класса.
Средний компонент/конструктор директив уже достаточно велик, потому что он может иметь многострочную подпись из-за зависимостей, добавляя ненужную логику инициализации в тело конструктора, что способствует антипаттерну.
Конструктор асинхронной инициализации часто можно считать антипаттерном и иметь запах, потому что создание экземпляра класса завершается раньше, чем асинхронная подпрограмма, и это может создавать условия гонки. Если это не так, 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
или ngOnInit
после создания экземпляра компонента.
В исключительных случаях ngOnInit
может быть полностью заглушен, чтобы обеспечить изоляцию для других компонентов (например, некоторой логики шаблона).
Дочерние классы могут только расширять конструкторы, но не заменять их.
Поскольку this
не может быть передано до super()
, это накладывает ограничения на приоритет инициализации.
Учитывая, что компонент или директива Angular использует ngOnInit
для логики нечувствительной ко времени инициализации, дочерние классы могут выбирать, super.ngOnInit()
ли super.ngOnInit()
и когда:
ngOnInit() {
this.someMethod();
super.ngOnInit();
}
Это было бы невозможно реализовать с помощью одного конструктора.
Вышеупомянутые ответы на самом деле не отвечают на этот аспект исходного вопроса: что такое крючок жизненного цикла? Мне потребовалось некоторое время, чтобы понять, что это значит, пока я не подумал об этом таким образом.
1) Скажите, что ваш компонент - человек. У людей есть жизни, которые включают многие этапы жизни, а затем мы истекли.
2) Наш человеческий компонент может иметь следующий жизненный цикл script: Born, Baby, Grade School, Young Adult, Mid-age Adult, Senior Adult, Dead, Disposed of.
3) Скажите, что вы хотите создать функцию для создания детей. Чтобы это не усложнилось и, скорее, юмористическое, вы хотите, чтобы ваша функция была вызвана только на этапе "Молодой взрослый" жизни человека. Таким образом, вы разрабатываете компонент, который активен только тогда, когда родительский компонент находится на стадии "Молодой взрослый". Крючки помогают вам это сделать, сигнализируя о том, что жизненный этап и позволить вашему компоненту действовать на нем.
Забавные вещи. Если вы позволите своему воображению пойти на такое кодирование, это становится сложным и забавным.
Угловые 2 Конструкторы: -
Угловое 2 ngOnInit: -
Событие ngOnInit представляет собой метод события цикла "Угловой 2", который вызывается после первого ngOnChanges, а метод ngOnInit используется для параметров, определенных с помощью @Input, иначе конструктор в порядке.
Вызывается ngOnInit после конструктора и ngOnInit вызывается после первого ngOnChanges.
Вызывается ngOnChanges при изменении значения привязки ввода или вывода.
Следующая диаграмма объясняет цикл лжи Углового. Из этого вы можете получить представление о порядке, в котором вызывается каждый.
Конструктор - это метод в 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) no Angular).
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");
}
}
Сначала мы создаем экземпляр класса, как показано ниже, с немедленными запусками метода конструктора.
let instance = new NGONINITTEST();
ngOnInit вызывается Angular при необходимости, как показано ниже:
instance.ngOnInit();
Но вы можете спросить, почему мы используем конструктор в Angular?
Ответ зависимостей инъекций. Как уже упоминалось ранее, вызовы конструктора движком JavaScript сразу после создания экземпляра класса (до вызова ngOnInit по Angular), поэтому typescript помогает нам получить тип зависимостей, определенных в конструкторе, и, наконец, сообщает Angular, какие типы зависимостей мы хотим использовать в этом конкретном компоненте.
Здесь есть две вещи:
Оба имеют разные удобства.
constructor() - метод по умолчанию в жизненном цикле Компонента и используется для инъекции зависимостей. Конструктор - это функция машинописного текста.
ngOnInit() вызывается после конструктора и ngOnInit вызывается после первого ngOnChanges.
т.е. Constructor() → ngOnChanges() → ngOnInit()
как упоминалось выше, ngOnChanges() вызывается, когда изменяется значение привязки ввода или вывода.
Оба метода имеют разные цели/обязанности. Задача конструктора (функция, поддерживаемая языком) состоит в том, чтобы убедиться, что инвариант представления имеет место. В противном случае указывается, чтобы убедиться, что экземпляр действителен, указав правильные значения членам. Разработчик должен решить, что означает "правильный".
Задача метода onInit() (которая представляет собой концепцию angular) заключается в разрешении вызова метода на правильный объект (инвариант представления). Каждый метод должен, в свою очередь, убедиться, что инвариант представления выполняется, когда метод завершается.
Конструктор должен использоваться для создания "правильных" объектов, метод onInit дает вам возможность вызывать вызовы методов в хорошо определенном экземпляре.
Конструктор: метод конструктора класса ES6 (или TypeScript в этом случае) является признаком самого класса, а не угловой. Его из углов управляет при вызове конструктора, а это означает, что он не подходит для того, чтобы сообщить вам, когда Angular завершил инициализацию компонента. JavaScript-движок вызывает конструктор, а не угловой напрямую. Именно поэтому был создан привязку ngOnInit (и $ onInit в AngularJS) жизненного цикла. Принимая это во внимание, существует подходящий сценарий для использования конструктора. Это когда мы хотим использовать инъекцию зависимостей - по существу для "подключения" зависимостей к компоненту.
Поскольку конструктор инициализируется движком JavaScript, а TypeScript позволяет нам рассказать, какие зависимости мы требуем для сопоставления с определенным свойством.
ngOnInit чисто здесь, чтобы дать нам сигнал, что Angular завершил инициализацию компонента.
Эта фаза включает первый проход при обнаружении изменения в отношении свойств, которые мы можем привязать к самому компоненту - например, с помощью декоратора @Input().
Благодаря этому свойства @Input() доступны внутри ngOnInit, но не определены внутри конструктора, по дизайну
Конструктор является первым, и это случается иногда, когда @input data null! поэтому мы используем конструктор для объявления сервисов и ngOnInit происходит после. Пример для контрагента:
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.
В Angular жизненных циклах
1) Angular параметр конструктора обнаружения инжектора (s) и экземпляр класса.
2) Следующий Angular жизненный цикл вызова
Angular Ключи жизненного цикла
ngOnChanges → Переключение обязательных параметров.
ngOnInit → Начать рендеринг Angular...
Вызов другого метода с состоянием жизненного цикла Angular.
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
};
Я нашел ответ и попытался перевести его на английский: этот вопрос все еще возникал, даже в технических интервью. На самом деле, между ними есть большое сходство, но есть и некоторые различия.
Конструктор является частью ECMAScript. С другой стороны, ngOnInit() - это понятие угловое.
Мы можем вызывать конструкторы во всех классах, даже если мы не используем Angular
LifeCycle: конструктор вызывается перед ngOnInt()
В конструкторе нельзя назвать элементы HTML. Однако в ngOnInit() мы можем.
Как правило, вызовы служб в ngOnInit(), а не в конструкторе
Источник: http://www.angular-tuto.com/Angular/Component#Diff
The
@Input
Механизм связиобрабатывается как часть следующей фазы обнаружения изменений, поэтому входные привязки недоступны в конструкторе.
constructor()
используется для инъекции зависимостей.
ngOnInit()
, ngOnChanges()
и ngOnDestroy()
и т.д. - методы жизненного цикла. ngOnChanges()
будет первым, который будет вызван, до ngOnInit()
, когда значение связанного свойства изменится, оно НЕ будет вызываться, если нет изменений. ngOnDestroy()
вызывается при удалении компонента. Чтобы использовать его, OnDestroy
должен быть implement
ed классом.
На самом деле, ngOnInit() по двум основным причинам:
1) Выполнить сложные инициализации вскоре после строительства.
2) Чтобы установить компонент после Angular, задайте входные свойства.
Опытные разработчики согласны с тем, что компоненты должны быть дешевыми и безопасными в изготовлении.
Миско Хевери, руководитель команды Angular, объясняет, почему вам следует избегать сложной логики конструктора.
Не выбирайте данные в конструкторе компонента. Вам не следует беспокоиться о том, что новый компонент попытается связаться с удаленным сервером при создании тестируемого сервера или до того, как вы решите его отобразить. Конструкторы должны делать не более, чем устанавливать начальные локальные переменные в простые значения.
NgOnInit() - хорошее место для компонента, чтобы получить его начальные данные.
Помните также, что входные свойства директивы с привязкой к данным не устанавливаются до окончания строительства. Это проблема, если вам нужно инициализировать директиву на основе этих свойств. Они будут установлены при запуске ngOnInit().
Метод ngOnChanges() - это ваша первая возможность получить доступ к этим свойствам. Angular вызывает ngOnChanges() до ngOnInit() и много раз после этого. Он только вызывает ngOnInit() один раз.
Вы можете рассчитывать на Angular для вызова метода ngOnInit() вскоре после создания компонента. Это где тяжелая логика инициализации.
Конструктор - это функция, выполняемая при сборке компонента (или другого класса).
ngOnInit - это функция, принадлежащая к группам методов жизненного цикла компонента, и они выполняются в другой момент нашего компонента (поэтому и называют жизненным циклом). Вот список всех из них:
Конструктор будет выполнен перед любой функцией жизненного цикла.
Конструктор Конструктор класса в Angular в основном используется для внедрения зависимостей. Angular вызывает этот шаблон инжектора конструктора, который подробно описан здесь. Для более глубокого понимания архитектуры вы можете прочитать "Инъекция конструктора против инъекции сеттера" Мишко Хевери.
Однако использование конструктора не ограничивается DI. Например, директива router-outlet модуля @angular/router использует его для регистрации себя и своего местоположения (viewContainerRef) в экосистеме маршрутизатора. Я описал этот подход в разделе Вот как получить ViewContainerRef до оценки запроса @ViewChild.
Тем не менее, обычная практика заключает в конструктор как можно меньше логики.
NgOnInit Как мы узнали выше, когда Angular вызывает ngOnInit, он завершил создание DOM компонента, внедрил все необходимые зависимости через конструктор и обработал привязки ввода. Так что здесь у вас есть вся необходимая информация, которая делает его хорошим местом для выполнения логики инициализации.
Обычной практикой является использование ngOnInit для выполнения логики инициализации, даже если эта логика не зависит от DI, DOM или привязок ввода.