简体   繁体   English

扩展组件上的角度注入器

[英]Angular injector on extended components

I am using ionic4 and Angular 7.2.2, and I created a base component class to be extended by other components and not have to repeat a lot of things that I always use. 我正在使用ionic4和Angular 7.2.2,我创建了一个基本组件类,可以被其他组件扩展,而不必重复我经常使用的很多东西。 In order to avoid the constructor injection, and therefore be forced to pass again the params to the base construtor in th extended class, I am using Injector.get. 为了避免构造函数注入,因此强制将params再次传递给扩展类中的基础construtor,我使用的是Injector.get。

The problem that experience is that, when used it this way, a lot of Angular or Ionic injectors that work fine if injected in the child constructor, do not work or return empty values when used in the child, using the parent's reference. 体验的问题是,当以这种方式使用它时,如果在子构造函数中注入,很多Angular或Ionic注入器工作正常,使用父项的引用时,在子项中使用时不起作用或返回空值。

I am sure there is something I am missing out, because upon inspection of the injector when using the one from my base class and the one from the child, they are different. 我确信我错过了一些东西,因为在使用我的基类中的一个和来自孩子的那个时检查注射器时,它们是不同的。

Uppon execution, and going to: http://localhost:8101/home/4 Uppon执行,并转到: http:// localhost:8101 / home / 4

This is the relevant code: 这是相关代码:

app-routing.module.ts APP-routing.module.ts



const routes: Routes = [
    {path: '', redirectTo: 'home/4', pathMatch: 'full'},
    {path: 'home/:id', loadChildren: './home/home.module#HomePageModule'},
];

home.page.ts home.page.ts

import {Component} from '@angular/core';
import {BasePage} from '../../tests/base.comp.test';
import {ActivatedRoute} from '@angular/router';

@Component({
    selector: 'app-home',
    templateUrl: 'home.page.html',
    styleUrls: ['home.page.scss'],
})
export class HomePage extends BasePage {

    constructor(public ar: ActivatedRoute) {
        super();


        this.activatedRoute.params.subscribe(
            (result) => {
                console.log(`PARAMS FROM inherited activatedRoute-> `, result); // -> outputs {} WRONG!

            }
        );

        ar.params.subscribe(
            (result) => {
                console.log(`Params from direct injection-> `, result); // -> outputs {id: "4"} Good!
            }
        );


    }

}

home.module.ts home.module.ts

import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {HomePage} from './home.page';
import {BasePageModule} from '../../tests/base.test.module';

@NgModule({
    imports: [
        BasePageModule,
        RouterModule.forChild([
            {
                path: '',
                component: HomePage
            }
        ])
    ],
    declarations: [HomePage]
})
export class HomePageModule {
}

base.test.module.ts base.test.module.ts

import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {IonicModule} from '@ionic/angular';
import {FormsModule} from '@angular/forms';
import {BasePage} from './base.comp.test';

@NgModule({
    imports: [
        CommonModule,
        IonicModule,
        FormsModule,
    ],
    declarations: [BasePage],
    providers: [],
    exports: [
        CommonModule,
        IonicModule,
        FormsModule
    ]
})
export class BasePageModule {
}

base.comp.test.ts base.comp.test.ts

import {Component, Injector} from '@angular/core';
import {AppInjectorTest} from './app.injector.test';
import {ActivatedRoute, Router} from '@angular/router';

@Component({
    selector: 'app-base',
    template: '',
})
export class BasePage {

    public injector: Injector;
    public activatedRoute: ActivatedRoute;

    constructor() {
        const injector = AppInjectorTest.getInjector();
        this.activatedRoute = injector.get(ActivatedRoute);
    }

}

app.injector.test.ts app.injector.test.ts

import {Injector} from '@angular/core';

export class AppInjectorTest {

    private static injector: Injector;

    static setInjector(injector: Injector) {
        AppInjectorTest.injector = injector;
    }

    static getInjector(): Injector {
        return AppInjectorTest.injector;
    }

}

app.component.ts app.component.ts

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

import {Platform} from '@ionic/angular';
import {SplashScreen} from '@ionic-native/splash-screen/ngx';
import {StatusBar} from '@ionic-native/status-bar/ngx';
import {AppInjectorTest} from '../tests/app.injector.test';

@Component({
    selector: 'app-root',
    templateUrl: 'app.component.html'
})
export class AppComponent {
    constructor(
        private platform: Platform,
        private splashScreen: SplashScreen,
        private statusBar: StatusBar,
        private injector: Injector
    ) {
        this.initializeApp();
        AppInjectorTest.setInjector(injector);
    }

    initializeApp() {
        this.platform.ready().then(() => {
            this.statusBar.styleDefault();
            this.splashScreen.hide();
        });
    }
}

For now it seems that the only workaround we want to do this is to re-inject the injector from the child into the parent. 目前看来,我们想要做的唯一解决方法是将注射器从子进程重新注入父进程。 It is not as clean as keeping the constructor completely empty, but, at least, you can extend and reuse a lot of logic from a parent component in a neat way. 它不像保持构造函数完全为空一样干净,但至少,你可以以一种简洁的方式扩展和重用父组件中的大量逻辑。

child.comp.ts (that extends from parent) child.comp.ts(从父级扩展)


    constructor(public injector: Injector) {
        super(injector);
    }

(...)

parent.comp.ts parent.comp.ts

(...)
    constructor(public injector: Injector) {
         this.activatedRoute = injector.get(ActivatedRoute);
    }

(...)

there is nothing wrong with your static injector but it related how activatedRoute work , ActivatedRoute contains the information about a route associated with a component. 静态注入器没有任何问题,但它与activateRoute的工作方式有关, ActivatedRoute包含有关与组件关联的路由的信息。 loaded in an outlet doc , thay whay the injected activatedRoute (component) work instad of base injected activatedrouteservice 装入插座 doc ,thay whay注入的激活路由器(组件)工作instad的基础注入activatedrouteservice

when using a parametrized route which targets a component, only this component can access those parameters. 当使用以组件为目标的参数化路由时,只有该组件可以访问这些参数。

check this question has similar problem 👉 How to retrieve a route param using Injector.get(ActivatedRoute)? 检查这个问题有类似的问题👉 如何使用Injector.get(ActivatedRoute)检索路由参数?

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

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