可以创建一个抽象属性吗?

时间:2017-09-20 17:41:09

标签: angular typescript

我在Child类中有一个看起来像这样的属性:

formModel = {
    motive: 0,
    coop: 0,
    leadership: 0,
    teamwork: 0,
    community: 0,
    professional: 0,
    role_model: 0,
    supportive: 0,
    problem_solving: 0
};

但在其他子类中,此属性不同。

formModel = {
    motive: 0,
    coop: 0,
    leadership: 0,
    teamwork: 0,
    community: 0,
    professional: 0,
    communication: 0,
    respect: 0,
    morale: 0,
    role_model: 0,
    supp_enviro: 0
};

属性的顺序发生变化,名称也会发生变化。

我想在其父类中声明此属性的abstract版本。这可能吗?我父母的public abstract formModel: Object;没有这么幸运。

编辑:

以下是我遇到的错误:

vendor.bundle.js:40839 Uncaught Error: Unexpected value 'undefined' declared by the module 'AppModule'
    at syntaxError (vendor.bundle.js:40839)
    at vendor.bundle.js:54719
    at Array.forEach (<anonymous>)
    at CompileMetadataResolver.webpackJsonp.../../../compiler/@angular/compiler.es5.js.CompileMetadataResolver.getNgModuleMetadata (vendor.bundle.js:54717)
    at JitCompiler.webpackJsonp.../../../compiler/@angular/compiler.es5.js.JitCompiler._loadModules (vendor.bundle.js:66103)
    at JitCompiler.webpackJsonp.../../../compiler/@angular/compiler.es5.js.JitCompiler._compileModuleAndComponents (vendor.bundle.js:66076)
    at JitCompiler.webpackJsonp.../../../compiler/@angular/compiler.es5.js.JitCompiler.compileModuleAsync (vendor.bundle.js:66005)
    at PlatformRef_.webpackJsonp.../../../core/@angular/core.es5.js.PlatformRef_._bootstrapModuleWithZone (vendor.bundle.js:71695)
    at PlatformRef_.webpackJsonp.../../../core/@angular/core.es5.js.PlatformRef_.bootstrapModule (vendor.bundle.js:71681)
    at Object.../../../../../src/main.ts (main.bundle.js:1339)

我注意到,如果我将以下方法添加到父类而不是子类,我只会收到此错误:

public handleRadioButtonChanges(event: Event): void {
    console.log("test");
}

2 个答案:

答案 0 :(得分:4)

所述问题的答案强调,您可以创建抽象属性。我可以做到以下没有错误:

// what are the restrictions on FormModel? 
// See [@amal's answer](https://stackoverflow.com/a/46328720/2887218) 
// for discussion about this
interface FormModel {
  [key: string]: number;
}

abstract class Parent {
  public abstract formModel: FormModel;  
  public handleRadioButtonChanges(event: Event): void {
    console.log("test");
}
}

class Child extends Parent {
  formModel = {
    motive: 0,
    coop: 0,
    leadership: 0,
    teamwork: 0,
    community: 0,
    professional: 0,
    role_model: 0,
    supportive: 0,
    problem_solving: 0
  };
}

class AnotherChild extends Parent {
  formModel = {
    motive: 0,
    coop: 0,
    leadership: 0,
    teamwork: 0,
    community: 0,
    professional: 0,
    communication: 0,
    respect: 0,
    morale: 0,
    role_model: 0,
    supp_enviro: 0
  };
}

但是,您收到的错误似乎是webpack特有的,我不知道是什么导致了它。当我使用tsc编译时,使用或不使用public abstract formModel: FormModel;行生成的JavaScript之间没有区别。它只是类型信息,往往不会进入JavaScript。您可能需要提供有关您的环境的更多信息,以便有人可以重现。

在任何情况下,您遇到的问题可能与抽象属性本身关系不大,只是在将该属性添加到父类时会暴露它。也许this GitHub issue是相关的?还是this SO question?我真的不知道,因为我没有任何网络专业知识。

答案 1 :(得分:1)

如果您只关心它的类型,可以为它定义一个接口。

export interface FormModel {
 motive: number;
 coop: number;
 leadership: number;
 teamwork: number;
 community: number;
 professional: number;
 role_model: number;
 supportive: number;
 problem_solving: number;
}

然后在child中,您可以简单地声明父类中定义的formModel类型FormModel(您还必须在子component.ts文件中导入此接口)。

import { FormModel } from 'app/<Interface's location>';

formModel: FormModel;

修改

如果有帮助,可以将?添加到motive?: number;的声明中,以使其成为可选项。因此,将此添加到您认为可选的属性中。或者只是简单地声明您认为总是存在的属性(没有可选),然后添加这样的动态属性。

export interface FormModel {
 motive: number;
 coop: number;
 leadership: number;
 teamwork: number;
 community: number;
 professional: number;
 role_model: number;
 supportive: number;
 problem_solving: number;
 [key: string]: any; // <-- leaving room for optional extra properties
}