简体   繁体   English

实例化 Injectable class 时未调用 ngOnInit

[英]ngOnInit not being called when Injectable class is Instantiated

Why isn't ngOnInit() called when an Injectable class is resolved?为什么在解析Injectable class 时不ngOnInit()

Code代码

import {Injectable, OnInit} from 'angular2/core';
import { RestApiService, RestRequest } from './rest-api.service';

@Injectable()
export class MovieDbService implements OnInit {

    constructor(private _movieDbRest: RestApiService){
        window.console.log('FROM constructor()');
    }

    ngOnInit() {
         window.console.log('FROM ngOnInit()');
    }

}

Console Output控制台 Output

FROM constructor()

Lifecycle hooks , like OnInit() work with Directives and Components.生命周期钩子,如OnInit()与指令和组件一起使用。 They do not work with other types, like a service in your case.它们不适用于其他类型,例如您的服务。 From docs:来自文档:

A Component has a lifecycle managed by Angular itself.组件的生命周期由 Angular 自己管理。 Angular creates it, renders it, creates and renders its children, checks it when its data-bound properties change and destroy it before removing it from the DOM. Angular 创建它,渲染它,创建和渲染它的子节点,当它的数据绑定属性发生变化时检查它,并在从 DOM 中删除它之前销毁它。

Directive and component instances have a lifecycle as Angular creates, updates, and destroys them.指令和组件实例在 Angular 创建、更新和销毁它们时具有生命周期。

I don't know about all the lifecycle hooks, but as for destruction, ngOnDestroy actually get called on Injectable when it's provider is destroyed (for example an Injectable supplied by a component).我不知道所有的生命周期钩子,但至于销毁, ngOnDestroy实际上在 Injectable 的提供者被销毁时被调用(例如由组件提供的 Injectable)。

From the docs :docs :

Lifecycle hook that is called when a directive, pipe or service is destroyed.当指令、管道或服务被销毁时调用的生命周期钩子。

Just in case anyone is interested in destruction check this question:以防万一有人对破坏感兴趣,请检查以下问题:

Adding to answer by @Sasxa ,添加@Sasxa 的回答

In Injectables you can use class normally that is putting initial code in constructor instead of using ngOnInit() , it works fine.Injectables中,您可以正常使用将初始代码放入constructor中的class ,而不是使用ngOnInit() ,它工作正常。

一旦我的 dataService 被初始化,我必须调用一个函数,相反,我在构造函数中调用它,这对我有用。

Note: this answer applies only to Angular components and directives, NOT services.注意:此答案仅适用于 Angular 组件和指令,不适用于服务。

I had this same issue when ngOnInit (and other lifecycle hooks) were not firing for my components, and most searches led me here.ngOnInit (和其他生命周期挂钩)没有为我的组件触发时,我遇到了同样的问题,并且大多数搜索都把我带到了这里。

The issue is that I was using the arrow function syntax ( => ) like this:问题是我使用的是箭头函数语法( => ),如下所示:

class MyComponent implements OnInit {
    // Bad: do not use arrow function
    public ngOnInit = () => {
        console.log("ngOnInit");
    }
}

Apparently that does not work in Angular 6. Using non-arrow function syntax fixes the issue:显然这在 Angular 6 中不起作用。使用非箭头函数语法解决了这个问题:

class MyComponent implements OnInit {
    public ngOnInit() {
        console.log("ngOnInit");
    }
}

we can trigger it by placing it in Constructor.我们可以通过将它放在构造函数中来触发它。 But what is the reason ngOnInit() is not triggering.但是 ngOnInit() 没有触发的原因是什么。

In your service you can use resolvers for the same purpose, as explained in this post: https://codeburst.io/understanding-resolvers-in-angular-736e9db71267 在您的服务中,您可以将resolvers用于相同的目的,如本博文所述: https : //codeburst.io/understanding-resolvers-in-angular-736e9db71267

To understand the use of resolvers, Lets see how the flow happens, when someone clicks the link. 为了了解解析器的用法,让我们看看当有人单击链接时流程如何发生。

General Routing Flow. 常规路由流程。

  • User clicks the link. 用户单击链接。
  • Angular loads the respective component. 角加载相应的组件。

Routing Flow with Resolver 使用解析器的路由流

  • User clicks the link. 用户单击链接。

  • Angular executes certain code and returns a value or observable. Angular执行某些代码并返回一个值或可观察值。

  • You can collect the returned value or observable in constructor or in ngOnInit, in class of your component which is about to load. 您可以在要加载的组件类中的构造函数或ngOnInit中收集返回值或可观察的值。

  • Use the collected the data for your purpose. 将收集的数据用于您的目的。

  • Now you can load your component. 现在您可以加载您的组件了。

Steps 2, 3 and 4 are done with a code called Resolver. 步骤2、3和4是使用称为Resolver的代码完成的。

As others have said, ngOnInit works on Components only. 正如其他人所说, ngOnInit仅在组件上起作用。

Use the constructor in Injectable() services. Injectable()服务中使用构造函数。 It will serve your needs in most cases. 在大多数情况下,它将满足您的需求。

import {Injectable, OnInit} from 'angular2/core';
import { RestApiService, RestRequest } from './rest-api.service';
import {Service} from "path/to/service/";

@Injectable()
export class MovieDbService implements OnInit {

userId:number=null;

constructor(private _movieDbRest: RestApiService,
            private instanceMyService : Service ){

   // do evreything like OnInit just on services

   this._movieDbRest.callAnyMethod();

   this.userId = this.instanceMyService.getUserId()


}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM