扩展组件上的角喷射器

时间:2019-07-03 08:04:37

标签: angular typescript

我正在使用ionic4和Angular 7.2.2,并且创建了一个基本组件类以由其他组件扩展,而不必重复很多我经常使用的事情。为了避免构造函数注入,并因此被迫将参数再次传递给扩展类中的基本构造函数,我使用了Injector.get。

体验的问题是,以这种方式使用时,许多Angular或Ionic注入器在子构造函数中注入时工作正常,在父子引用中不起作用或在子项中返回空值

我敢肯定我会漏掉一些东西,因为在检查喷油器时,使用的是我基类的那一种和儿童的那一种,它们是不同的。

执行后,转到: http://localhost:8101/home/4

这是相关代码:

app-routing.module.ts



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

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

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

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

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

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

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

2 个答案:

答案 0 :(得分:2)

目前看来,我们要做的唯一解决方法是将注入器从子级重新注入父级。它不像使构造函数完全为空那样干净,但是至少,您可以以一种简洁的方式扩展和重用父组件中的许多逻辑。

child.comp.ts(从父级延伸)


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

(...)

parent.comp.ts

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

(...)

答案 1 :(得分:1)

您的静态注射器没有什么问题,但它与ActivateRoute的工作方式有关, ActivatedRoute 包含有关与组件关联的路线的信息。加载到插座 doc中的方式,基础注入的Activatedrouteservice注入的ActivatedRoute(组件)工作方式为

  

使用针对组件的参数化路线时,仅此   组件可以访问这些参数。

检查此问题是否有类似的问题?How to retrieve a route param using Injector.get(ActivatedRoute)?