当前位置: 首页 > 知识库问答 >
问题:

Angular 2.3组件继承和依赖注入

巫研
2023-03-14

如何使用新的Angular 2.3组件继承在子组件和父组件之间共享依赖注入?

例如,我想将AlertService移到父组件中,并将TraingCompanyService留在派生组件中

当前组件

@Component({
    selector: 'wk-training-company-edit',
    template: require('./edit.html')
})
export class TrainingCompanyEditComponent implements OnInit, OnDestroy {

    constructor(
                private alert: AlertService,
                private trainingCompanyService: TrainingCompanyService
                ) {

    }
}

重构组件 (V1)

在派生类的构造函数中调用Super之前,必须先调用它

@Component({
    selector: 'wk-training-company-edit',
    template: require('./edit.html')
})
export class TrainingCompanyEditComponent extends BaseAdminEditComponent implements OnInit, OnDestroy {

    constructor(
                private alert: AlertService,
                private trainingCompanyService: TrainingCompanyService
                ) {

        // Error: Super must be called before calling this in the constructor of the derived class
        super(this.alert);
    }
}

export class BaseAdminEditComponent {

    constructor(private alert: AlertService) {
    }

    protected handleSaveError(error: any) {

        if (error.message) {
            if (error.errors && _.isArray(error.errors) && error.errors.length > 0) {
                this.alert.error(_.join(error.errors, '\n'), error.message);
            }
            else {
                this.alert.error(error.message);
            }
        }
    }
}

重构组件(V2)

类培训公司编辑组件错误地扩展基类 BaseAdminEditComponent,类型具有单独的私有属性声明“alert”

@Component({
    selector: 'wk-training-company-edit',
    template: require('./edit.html')
})
export class TrainingCompanyEditComponent extends BaseAdminEditComponent implements OnInit, OnDestroy {

    // Class TrainingCompanyEditComponent incorrectly extends base class BaseAdminEditComponent, types have seperate declarations of private property 'alert'
    constructor(
                private alert: AlertService,
                private trainingCompanyService: TrainingCompanyService
                ) {

        // alert instead of this.alert
        super(alert);
    }
}

export class BaseAdminEditComponent {

    constructor(private alert: AlertService) {
    }

    protected handleSaveError(error: any) {

        if (error.message) {
            if (error.errors && _.isArray(error.errors) && error.errors.length > 0) {
                this.alert.error(_.join(error.errors, '\n'), error.message);
            }
            else {
                this.alert.error(error.message);
            }
        }
    }
}

重构组件(V3)

这是有效的,只是想知道这是不是最好的技术

@Component({
    selector: 'wk-training-company-edit',
    template: require('./edit.html')
})
export class TrainingCompanyEditComponent extends BaseAdminEditComponent implements OnInit, OnDestroy {

    // Class TrainingCompanyEditComponent incorrectly extends base class BaseAdminEditComponent, types have seperate declarations of private property 'alert'
    constructor(
                private alert: AlertService,
                private trainingCompanyService: TrainingCompanyService
                ) {

        // alert instead of this.alert
        super(alert);
    }
}

export class BaseAdminEditComponent {

    // Create a private variable with a different name, e.g. alert2
    private alert2: AlertService;

    constructor(alert: AlertService) {
        this.alert2 = alert;
    }

    protected handleSaveError(error: any) {

        if (error.message) {
            if (error.errors && _.isArray(error.errors) && error.errors.length > 0) {
                this.alert2.error(_.join(error.errors, '\n'), error.message);
            }
            else {
                this.alert2.error(error.message);
            }
        }
    }

}

共有3个答案

尉迟鸿熙
2023-03-14

带有修饰符关键字的构造函数定义如下

export class TrainingCompanyEditComponent 
    extends BaseAdminEditComponent implements OnInit, OnDestroy {

    constructor(
        private alert: AlertService,
        private trainingCompanyService: TrainingCompanyService
    ) {
    }
    ...

只是一个更详细的语法糖:

export class TrainingCompanyEditComponent 
    extends BaseAdminEditComponent implements OnInit, OnDestroy {

    private alert: AlertService,
    private trainingCompanyService: TrainingCompanyService

    constructor(
        alert: AlertService,
        trainingCompanyService: TrainingCompanyService
    ) {
        this.alert = alert; // assign incoming value to member
        this.trainingCompanyService = trainingCompanyService;
    }
    ...

所以,这是在后台。我们只能在调用超级时执行该分配…这就是为什么我们必须使用this.alert(访问成员)将调用更改为警报(传递传入值)

    constructor(
        private alert: AlertService,
        private trainingCompanyService: TrainingCompanyService
    ) {
        //super(this.alert);
        super(alert); // this.alert was not assign yet

        // next ?
        // the this.alert will be assigned for us...
    }

在这里玩这个调整后的定义

唐钊
2023-03-14

我终于找到了有效的模式,重要的是不要使用 Radim 在构造函数中提到的私有(syntact suger 模式)。

我将警报服务作为基类的受保护属性。

将基本事件处理程序绑定到此< code > handlersaveerror . bind(this)非常重要

最终工作代码在这里。

基本类

import * as _ from "lodash";

import {AlertService} from '../common/alert/alert.service';

export class BaseAdminEditComponent {

    protected alert: AlertService;

    constructor(alert: AlertService) {
        this.alert = alert;
    }

    protected handleSaveError(error: any) {

        if (error.message) {
            if (error.errors && _.isArray(error.errors)) {
                console.error(error.errors);
            }
            this.alert.error(error.message);
        }
    }
}

组件实例类

@Component({
    selector: 'wk-training-company-edit',
    template: require('./edit.html')
})
export class TrainingCompanyEditComponent extends BaseAdminEditComponent {

    trainingCompany: TrainingCompany;

    trainingCompanyId: number;

    constructor(alert: AlertService, // Don't use private property
                private validation: ValidationService,
                private trainingCompanyService: TrainingCompanyService) {

        super(alert);

        // Other Constructor Code Here
    }

    onSave($event) {

        console.log('Save TrainingCompany');

        this.trainingCompany = TrainingCompany.fromJson(this.form.value);

        console.log(JSON.stringify(this.trainingCompany, null, 2));

        var isNew = _.isNil(this.trainingCompany.id);

        this.trainingCompanyService
            .upsert$(this.trainingCompany)
            .subscribe((response: EntityResponse<TrainingCompany>) => {

                try {
                    this.alert.success('TrainingCompany updated');

                    this.modelChange.fire('training-company', isNew ? 'new' : 'update', this.trainingCompany);
                }
                catch (e) {
                    console.error(e);
                    throw e;
                }
            }, this.handleSaveError.bind(this)); // Common Error Handler from base class. NOTE: bind(this) is required

    }
}
湛财
2023-03-14

只需将派生类中构造函数参数的访问修饰符设置在与基类相同的级别即可。即

基本类

import * as _ from "lodash";

import {AlertService} from '../common/alert/alert.service';

export class BaseAdminEditComponent {

    constructor(protected alert: AlertService) { }

    protected handleSaveError(error: any) {

        if (error.message) {
            if (error.errors && _.isArray(error.errors)) {
                console.error(error.errors);
            }
            this.alert.error(error.message);
        }
    }
}

派生类

@Component({
    selector: 'wk-training-company-edit',
    template: require('./edit.html')
})
export class TrainingCompanyEditComponent extends BaseAdminEditComponent {

    trainingCompany: TrainingCompany;

    trainingCompanyId: number;

    constructor(
        protected alert: AlertService,
        private validation: ValidationService,
        private trainingCompanyService: TrainingCompanyService) {

        super(alert);

        // Other Constructor Code Here
    }
}
 类似资料:
  • 在angular2中,假设我有一个类和一个类,它们具有相同的属性/成员和方法。如何初始化类? 服务 其中一个子类要扩展类:

  • 问题内容: 设我有5个Spring Boot项目。它们都对带有某些共享/公共类的Spring Boot项目No.6具有Maven依赖性。5个独立项目在每个application.properties中分配了很多通用属性,我想对其进行抽象并将其移至通用项目。总体看起来像这样: 当前的问题是app-common.properties在project1.jar / lib / common-projec

  • quote.component.ts 此组件依赖于来获取随机报价,然后它将显示。 类很简单 - 它只有getQuote函数,它将修改DOM,因此它将是我们测试的主要目标。 为了测试这个组件,我们需要启动QuoteComponent类。 Angular测试库提供了一个名为TestBed的实用程序。 这允许我们配置一个测试模块,我们可以提供模拟依赖。 此外,它将为我们创建组件并返回一个组件fixtur

  • 我有一个maven工件(),它依赖于某个工件()。 有一个父pom,其中包含某些其他依赖项。 是否可以使用这些依赖项,而无需在其自身pom的依赖项部分中明确添加它们?

  • 本文向大家介绍JS继承之借用构造函数继承和组合继承,包括了JS继承之借用构造函数继承和组合继承的使用技巧和注意事项,需要的朋友参考一下 借用构造函数继承  在解决原型中包含引用类型值所带来问题的过程中,开发人员开始使用一种叫做借用构造函数(constructor stealing)的技术(有时候也叫做伪造对象或经典继承)。这种技术的基本思想相当简单,即在子类型构造函数的内部调用超类型构造函数。 

  • 我在PHP中重构旧的应用程序。 我试图使用Symfony依赖注入组件将服务注入控制器(或其他服务),但我不知道如何实现这一点,因为symphony文档比框架组件更适合使用框架。 我已经有了自己的内核,包含所有服务和控制器的容器(控制器已经注册为服务)。我的控制器从扩展AbstractController。所以我现在唯一能做的就是: 通过