Різниця між конструктором та ngOnInit


1072

Angular ngOnInitза замовчуванням забезпечує гачок життєвого циклу .

Навіщо ngOnInitйого використовувати, якщо у нас вже є constructor?


11
ей, перевіри мою відповідь, яка пояснює різницю з точки зору внутрішніх робіт Angular
Макс Корецький


1
@MaximKoretskyi, ваше посилання мертве.
Yash Capoor

Відповіді:


1108

Це Constructorметод за замовчуванням класу, який виконується при інстанціюванні класу та забезпечує належну ініціалізацію полів у класі та його підкласах. Кутовий або краще залежний інжектор (DI) аналізує параметри конструктора і коли він створює новий екземпляр, викликаючи new MyClass()його, намагається знайти провайдерів, які відповідають типам параметрів конструктора, вирішує їх і передає їх конструктору, як

new MyClass(someArg);

ngOnInit це гак життєвого циклу, який називається Angular, щоб вказати, що Angular робиться для створення компонента.

Ми повинні імпортувати OnInitтак, щоб використовувати його (реальна реалізація OnInitне є обов'язковою, але вважається хорошою практикою):

import { Component, OnInit } from '@angular/core';

то для використання make нам методу 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()для налаштування Dependency Injection, а не багато іншого. ngOnInit () - краще місце для "запуску" - саме там / коли вирішуються прив'язки компонентів.

Для отримання додаткової інформації дивіться тут:


62
Саме в більшості (або навіть у всіх) мовах на основі класів є регулятори, які забезпечують належний порядок ініціалізації, особливо класів, які розширюють інші класи, де можуть виникнути деякі досить складні проблеми, як-от заключні поля (не знаю, чи є в них) і подібні. Конструктори не пов'язані з Angular2, вони є функцією TypeScript. Гачки життєвого циклу викликаються Angular після того, як відбулася деяка ініціалізація або коли відбулася якась подія, щоб дозволити компоненту діяти в певних ситуаціях і дати йому можливість виконувати деякі завдання в потрібний час.
Günter Zöchbauer

12
У angular.io/docs/ts/latest/guide/server-communication.html є блок-цитата, яка також пояснює це: "Компоненти простіше перевірити та налагодити, коли їх конструктори прості, а всі реальні роботи (особливо виклики віддалений сервер) обробляється окремим методом. " - У цьому випадку цей метод - ngOnInit ()
yoonjesung

3
це гак життєвого циклу, який називається Angular2, щоб вказати, що Angular робиться для створення компонента. - це не зовсім так. це сигналізує про те, що вона ініціалізувала прив'язки. Компонент створений раніше. Дивіться мою відповідь
Макс Корецький

22
Як і у всіх "найкращих практиках", я вважаю, що було б добре також пояснити, чому ви не повинні робити "роботу" в конструкторі. Ця стаття керівництва команди Angular є щільною, але може допомогти: misko.hevery.com/code-reviewers-guide/… Крім того, менше значення слід приділяти закликам, необхідним для впровадження OnInit (це легко знайти) та ін. критичний факт, що прив'язки даних недоступні в конструкторі.
Рейкім

2
Якщо строгий режим відповідає справжньому tsconfig.jsonфайлу "strict": true, то вам доведеться ініціалізувати учасників класу в constructor, а не в ngOnitподібних FormGroup.
Рохіт Шарма

169

У статті Суттєва відмінність між конструктором та ngOnInit у Angular досліджує різницю з різних точок зору. Ця відповідь надає найважливіше розбіжність пояснень, пов’язаних із процесом ініціалізації компонентів, який також показує різні за використанням.

Кутовий процес завантаження складається з двох основних етапів:

  • побудова компонента дерева
  • запуск виявлення змін

Конструктор компонента називається, коли Angular будує дерево компонентів. Усі гачки життєвого циклу називаються частиною виявлення змін роботи.

Коли Angular будує компоненти компонентів, інжектор кореневого модуля вже налаштований, так що ви можете вводити будь-які глобальні залежності. Крім того, коли Angular інстанціює клас дочірнього компонента, інжектор для батьківського компонента також вже встановлений, щоб ви могли вводити провайдерів, визначених для батьківського компонента, включаючи сам батьківський компонент. Конструктори компонентів - єдиний метод, який викликається в контексті інжектора, тому якщо вам потрібна залежність, це єдине місце, щоб отримати ці залежності.

Коли Angular починає виявлення змін, будується дерево компонентів і викликаються конструктори для всіх компонентів у дереві. Також до DOM додаються вузли шаблонів кожного компонента. Механізм @Inputзв’язку обробляється під час виявлення змін, тому ви не можете розраховувати на наявність властивостей у конструкторі. Він буде доступний після ngOnInit.

Подивимося короткий приклад. Припустимо, у вас є такий шаблон:

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

Тож Angular починає завантажувати додаток. Як я вже говорив, спочатку створюються класи для кожного компонента. Так він називає MyAppComponentконструктор. Він також створює вузол DOM, який є головним елементом my-appкомпонента. Потім переходить до створення хост-елемента для конструктора child-compі виклику ChildComponent. На цьому етапі це насправді не стосується iвведення прив'язки та будь-яких гаків життєвого циклу. Отже, коли цей процес закінчений, кутовий закінчується таким деревом переглядів компонентів:

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

Тільки тоді виконується виявлення змін та оновлення прив’язок для класу MyAppComponent my-appта викликів ngOnInit. Потім переходить до оновлення зв'язків для child-compі викликів ngOnInitкласу ChildComponent.

Ви можете виконувати свою логіку ініціалізації в будь-якому конструкторі або ngOnInitзалежно від того, що вам потрібно. Наприклад, стаття Ось як отримати ViewContainerRef перед тим, як буде оцінено запит @ViewChild, показано, який тип логіки ініціалізації може бути необхідний для виконання в конструкторі.

Ось кілька статей, які допоможуть вам краще зрозуміти тему:


33
це має бути прийнятою відповіддю. це насправді пояснює ЧОМУ замість повторення мантр та постановки the constructor should only be used to inject dependencies.
Ставм

1
@ yannick1976, дякую! Перегляньте посилання на статті
Макс Корецький,

@flobacca, чи можете ви перефразувати питання, важко зрозуміти, що ви запитуєте
Макс Корецький

Будь ласка, виправте мене, якщо я помиляюся. Я зрозумів, що компонентне дерево спочатку будується, а потім змінює процес виявлення. Ви писали, спочатку викликається конструктор AppComponent (разом із вирішеними залежностями), потім викликається конструктор ChildComponent (разом із залежностями), потім прив'язки вводу для AppComponent, а потім - OnInit. Але я хвилююся, якщо я додаю гачки життєвого циклу до обох компонентів, потік - AppComponentConstructor - -> AppComponentOnInit - → ChildComponentConstructor - → ChildComponentOnInit Чому AppComponentOnInit викликається перед ChildComponentConstructor
користувач2485435

1
@MaxKoretskyiakaWizard Ви мали рацію. Я зробив помилку в налаштуванні програми. він працює, як описано вами. angular-c7zjsx.stackblitz.io
користувач2485435

93

Я думаю, що найкращим прикладом може бути використання сервісів. Скажімо, що я хочу захопити дані зі свого сервера, коли мій компонент стане "Активований". Скажімо, що я також хочу зробити деякі додаткові речі до даних після того, як я отримаю їх із сервера, можливо, я отримаю помилку і хочу вписати їх по-іншому.

З 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 та заповнити свій список користувачів, але, можливо, я хочу зробити з ним деякі додаткові речі. Як і переконайтеся, що все в верхньому регістрі, я не зовсім впевнений, як надходять мої дані.

Так це значно полегшує використання 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();
    };


}

Це набагато простіше бачити, і тому я просто викликаю свою функцію в межах свого компонента, коли я ініціалізуюсь, а не потрібно копати її десь в іншому місці. Дійсно, це просто ще один інструмент, який ви можете використовувати для полегшення читання та використання в майбутньому. Крім того, я вважаю, що це дуже погана практика розміщувати функціональні виклики в конструкторі!


Ваш приклад може бути спрощений, якби ви просто встановили список_користувача на пункт Спостереження. Angular2 має трубу асинхронізації, тому там не виникне жодних проблем.
DarkNeuron

@Morgan, просто для того, щоб я дізнався тут дрібницю, чому ви спочатку створюєте функцію, getUsersа потім вставляєте її в ngOnInit? Чи не менш код просто записати його в ngOnInit? Мені цікаво, чому люди так роблять? Це так, що ви можете повторно використовувати код, якщо ви теж хотіли? Дякую.
Альфа Браво

31
Як видно з відповіді нижче, це не має значення, якщо це в конструкторі. Це не реальна відповідь на мету.
Джиммі Кейн

8
Я не бачу, як це відповідає на питання взагалі. Чому ви не могли просто поставити код у constructor?
CodyBugstein

1
@Morgan чому ти просто не можеш це зробитиconstructor(private _userService: UserService){ this.getUsers(); };
Ешлі

82

Гаразд, перш за все ngOnInitце частина життєвого циклу Angular , тоді як constructorє частиною класу JavaScript ES6 JavaScript, тому основна різниця починається саме тут! ...

Подивіться на нижню діаграму, яку я створив, яка показує життєвий цикл Angular.

ngOnInit vs конструктор

У 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
Дякую. це має бути найкращою відповіддю.
Дон Діланга

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
Ні. Для @ViewChildrenзокрема, потрібно використовувати ngAfterViewInitметод. Дивіться тут: stackoverflow.com/questions/46314734 / ...
AsGoodAsItGets

1
Дякую, @AsGoodAsItGets за вказівку на це. Зараз я покращив відповідь
Мирослав Йонас

38

Коротка і проста відповідь буде:

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

Ви можете перевірити цю невеличку демонстрацію, яка показує реалізацію обох речей.


5
Я думаю, що "конструктор - це те, що запускається або викликається при ініціалізації компонента". вводить в оману. Конструктор - це особливість класу, не компонента. Я б сказав, що екземпляр класу стає компонентом лише після виклику конструктора і Angular зробив його ініціалізацію.
Günter Zöchbauer

Так, змінили заяву, яку ви можете перевірити зараз.
мікроніки

1
Гм, ІМХО, все одно той самий "конструктор (метод за замовчуванням) - це те, що запускається або викликається при побудові компонента." Він викликається не тільки при створенні компонента, але і для служб або коли new MyClass()виконується подібний код . Я думаю, що вводити в оману твердження, що конструктори стосуються компонентів, про класи та ініціалізацію примірників цих класів. Компонент просто такий клас. Інакше я думаю, що це хороша відповідь.
Günter Zöchbauer

2
Так абсолютно. Забув згадати, що коли ви створюєте об'єкт класу, також constructorназивали б цей час . Але ця відповідь була написана у angular2 контексті. Щоб знати найкращу відповідь, ви повинні знати основи OOP. Я все-таки оновлю відповідь.
мікроніки

@ GünterZöchbauer, я не думаю, що це правильне твердження, яке є особливістю класу, а не компонента . З точки зору мови програмування так, це правильно. Але я можу успішно працювати з компонентами без жодних гачків життєвого циклу. Але я не можу працювати з компонентом без конструктора, якщо мені потрібен DI, тому що це єдине місце для ін'єкцій. Дивіться мою відповідь
Макс Корецький

20

Як і багато інших мов, ви можете ініціалізувати змінні на рівні класу, конструкторі чи методі. Розробник вирішує, що найкраще в їх конкретному випадку. Але нижче наведено перелік найкращих практик щодо прийняття рішення.

Змінні рівня класу

Зазвичай ви декларуєте тут усі свої змінні, які будуть використовуватися в решті компонента. Ви можете їх ініціалізувати, якщо значення не залежить від іншого, або використовувати ключове слово const для створення констант, якщо вони не зміняться.

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

Конструктор

Зазвичай найкраща практика нічого не робити в конструкторі, а просто використовувати його для класів, які будуть введені. Більшість часу ваш конструктор повинен виглядати так:

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

це автоматично створить змінні рівня класу, тому ви будете мати доступ до customService.myMethod()цього, не роблячи це вручну.

NgOnInit

NgOnit - це гак життєвого циклу, що надається рамкою Angular 2. Ваш компонент повинен реалізувати OnInitдля того, щоб використовувати його. Цей гак життєвого циклу викликається після виклику конструктора та ініціалізації всіх змінних. Основна частина вашої ініціалізації повинна йти сюди. Ви будете впевнені, що 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

Основна відмінність між конструктором і в 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
}

Ін'єкційна залежність

Основна роль конструкторів класу в кутовій куті - це введення залежності. Конструктори також використовуються для анотації 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може бути повністю закріплено, щоб забезпечити ізоляцію для інших компонентів (наприклад, певної логіки шаблону).

Спадщина

Дитячі класи можуть лише збільшувати конструктори, а не замінювати їх.

Оскільки thisдо super()цього не можна звернутися , це ставить обмеження на пріоритет ініціалізації.

Враховуючи, що кутовий компонент або директива використовує ngOnInitдля логіки ініціалізації нечутливі до часу, дочірні класи можуть вибирати super.ngOnInit(), викликається чи коли:

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

Це неможливо реалізувати лише з конструктором.


12

Наведені вище відповіді насправді не відповідають цьому аспекту оригінального питання: Що таке гачок життєвого циклу? Мені знадобилося певний час, щоб зрозуміти, що це означає, поки я не подумав про це таким чином.

1) Скажіть, ваш компонент - людина. У людей є життя, яке включає багато етапів життя, і тоді ми закінчуємось.

2) Наш людський компонент може мати такий сценарій життєвого циклу: Народжений, Дитина, Школа класу, Молодий дорослий, Дорослий середній вік, Старший Дорослий, Мертвий, Позбавлений.

3) Скажіть, що ви хочете мати функцію для створення дітей. Щоб це не стало складним і досить жартівливим, ви хочете, щоб ваша функція була викликана лише під час стадії молодих дорослих в житті людських компонентів. Таким чином, ви розробляєте компонент, який є активним лише тоді, коли батьківський компонент знаходиться на стадії молодого дорослого. Гачки допоможуть вам це зробити, сигналізуючи про той етап життя і дозволяючи своєму компоненту діяти на ньому.

Веселі речі. Якщо ви дозволите своїй уяві насправді кодувати щось подібне, це стає складним і смішним.


7

Конструктор являє собою метод в JavaScript і розглядається як ознака класу в ES6 При клас конкретизується відразу не запускається конструктор він використовується в кутових рамках або not.So його називають двигуном JavaScript і Кутова не має контроль над цим.

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

Спочатку ми інстанціюємо клас, як показано нижче, що відбувається з негайними запусками конструкторського методу.

let instance = new NGONINITTEST();

ngOnInit викликається Angular, коли необхідно, як нижче:

instance.ngOnInit();

Але ви можете запитати, чому ми використовуємо конструктор у Angular?

Відповідь - це ін'єкції залежностей . Як було сказано раніше, конструктор викликає двигун JavaScript негайно, коли клас створюється миттєво (перед викликом ngOnInit по Angular), тому машинопис допомагає нам визначити тип залежностей, визначених у конструкторі, і нарешті повідомляє Кутовий, який тип залежностей ми хочемо використовувати в конкретному компоненті.


7

Тут слід спостерігати дві речі:

  1. Конструктор викликається, коли створюється об'єкт цього класу.
  2. ngOnInit викликається після створення компонента.

Обидва мають різну юзабіліті.


5

constructor () - метод за замовчуванням у життєвому циклі компонента і використовується для введення залежності. Конструктор - це функція машинопису.

ngOnInit () викликається після конструктора, а ngOnInit викликається після перших ngOnChanges.

тобто:

Constructor () -->ngOnChanges () -->ngOnInit ()

як згадувалося вище ngOnChanges(), називається, коли змінюється значення прив'язки вводу або виходу.


4

Обидва методи мають різні цілі / обов'язки. Завдання конструктора (який є мовою, що підтримується мовою) - переконатися, що інваріант подання має місце. В іншому випадку зазначено, щоб переконатися, що примірник дійсний, надаючи правильні значення членам. Розробник вирішує, що означає "правильний".

Завдання методу onInit () (що є кутовим поняттям) полягає в тому, щоб дозволити виклики методу на правильний об'єкт (інваріантне представлення). Кожен метод повинен у свою чергу переконатися, що інваріант представництва виконується, коли метод припиняється.

Конструктор слід використовувати для створення "правильних" об'єктів, метод onInit дає можливість викликати виклики методів у чітко визначеному екземплярі.


4

Конструктор: Метод конструктора для класу ES6 (або TypeScript в даному випадку) є особливістю самого класу, а не функцією Angular. Коли виклик конструктора виходить з-під контролю Angular, це означає, що це не підходящий гачок, щоб повідомити, коли Angular закінчив ініціалізувати компонент. Двигун JavaScript викликає конструктор, а не кутовий безпосередньо. Саме тому було створено гак життєвого циклу ngOnInit (і $ onInit в AngularJS). Зважаючи на це, існує підходящий сценарій використання конструктора. Це коли ми хочемо використовувати ін'єкцію залежності - по суті для "з'єднання" залежностей у компоненті.

Оскільки конструктор ініціалізується двигуном JavaScript, а TypeScript дозволяє нам повідомити Angular, які залежності нам потрібні, щоб бути відображеними щодо конкретного властивості.

ngOnInit суто є, щоб подати нам сигнал про те, що Angular закінчив ініціалізувати компонент.

Ця фаза включає перший пропуск при виявленні змін проти властивостей, які ми можемо прив’язати до самого компонента - наприклад, за допомогою декоратора @Input ().

Завдяки цьому властивості @Input () доступні всередині ngOnInit, проте вони не визначені всередині конструктора, за задумом


2

Конструктор є першим, і це трапляється іноді, коли дані @input недійсні! тому ми використовуємо Constructor для оголошень служб, і 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.


1

У кутових життєвих циклах

1) Кутовий інжектор виявляє параметри конструктора (и) та інстанціональний клас.

2) Наступний життєвий цикл кутового дзвінка

Кутові гачки життєвого циклу

ngOnChanges -> Виклик прив’язки параметрів директиви.

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 () - для маніпулювання компонентами з необхідними викликами службової функції.
Стів

0

Я знайшов відповідь і спробував перекласти її англійською мовою: це питання все ще виникало навіть у технічних інтерв'ю. Насправді велика схожість між ними, але також є деякі відмінності.

  • Конструктор є частиною ECMAScript. З іншого боку, ngOnInit () - поняття кутового.

  • Ми можемо викликати конструктори в усіх класах, навіть якщо ми не використовуємо Angular

  • LifeCycle: конструктор викликається перед ngOnInt ()

  • У конструкторі ми не можемо викликати елементи HTML. Однак у ngOnInit () ми можемо.

  • Як правило, виклики служб в ngOnInit (), а не в конструкторі

    Джерело: http://www.angular-tuto.com/Angular/Component#Diff


0

Конструктор

Функція конструктора поставляється з кожним класом, конструктори не характерні для кутових, але є концепціями, похідними від об'єктно-орієнтованих конструкцій. Конструктор створює екземпляр класу компонентів.

OnInit

Ця ngOnInitфункція є одним із методів життєвого циклу кутового компонента. Методи життєвого циклу (або гачки) в кутових компонентах дозволяють запускати фрагмент коду на різних етапах життєдіяльності компонента. На відміну від методу конструктора, ngOnInitметод походить від кутового інтерфейсу ( OnInit), який компонент повинен реалізувати для використання цього методу. ngOnInitВикликається метод незабаром після того , як компонент створений.


0

Конструктор виконується, коли клас інстанціюється. Це не має нічого спільного з кутовим. Це особливість Javascript і Angular не має контролю над ним

NgOnInit має кутовий характер і називається, коли Angular ініціалізує компонент з усіма його вхідними властивостями

Властивості @Input доступні під гаком життєвого циклу ngOnInit. Це допоможе вам зробити деякі ініціалізаційні матеріали, такі як отримання даних із бек-енд-сервера тощо для відображення у поданні

@ Вхідні властивості відображаються як невизначені всередині конструктора


-1

Конструктор - це функція, що виконується при побудові компонента (або іншого класу).

ngOnInit - це функція, що належить до груп методів життєвого циклу компонентів, і вони виконуються в різний момент нашого компонента (саме тому називають життєвий цикл). Ось перелік усіх:

введіть тут опис зображення Конструктор буде виконаний перед будь-якою функцією життєвого циклу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.