这与在打字稿中扩展2类有点类似,但是尽管我设法在打字稿中做到了这一点,但我找不到在angular中正确的方法。
我有一个带有1个组件,一个服务和一个通用类的angular 7应用。
就像这样Stackblitz
我想制作一个继承自我的类的组件,以及其他组件
这是我的课=>
export class MyClass1<T,O> {
propertyClass1 = "MyClass1"
constructor() {
}
init(value:string){
this.propertyClass1 = value;
}
sayHelloClass(value:string){console.log('class say'+ value)}
}
这里是我的组件=>
export class MyCom1Component implements OnInit {
propertyComp1 = "MyCom1"
constructor(private service1:Service1Service) {
this.propertyComp1 = service1.getProp();
}
ngOnInit() {
}
sayHelloComponent(value:string){console.log('component say'+ value)}
}
我希望我的孩子能扩展展位,以便我能做
ngOnInit() {
this.sayHelloClass(this.propertyClass1); // class say MyClass1
this.init("hoohoho");
this.sayHelloClass(this.propertyClass1); // class say hoohoho
this.sayHelloComponent(this.propertyComp1); // component say MyCom1
}
我尝试的是这个=>
const addMyClassOneInheritance = <T extends new(...args: any[]) => any>(MyCom1Component: T) => {
return class extends MyCom1Component {
constructor(...args: any[]) {
super(...args);
}
};
};
const MyMergedClass = addMyClassOneInheritance(MyClass1);
export class ChildComponent extends MyMergedClass<string,number> {
ngOnInit(){
this.sayHelloClass(this.propertyClass1); // compile ok, execute give a value
this.sayHelloComponent(this.propertyComp1); // compile ok, execute "can't find sayHelloComponent
}
}
编译器没有给出错误,但我的组件方法未继承
答案 0 :(得分:4)
我建议采用另一种方法。
通过用@Injectable
然后像往常一样扩展父组件:ChildComponent extend MyCom1Component
,并使用MyClass1
的构造函数注入ChildComponent
最后,使用刚刚注入的类的实例调用父级的构造函数。
constructor(public myclass1: MyClass1) {
super(myclass1);
}
答案 1 :(得分:2)
Angular不允许Multiple Inheritance
。尽管可以extend only one class
,但也可以implement multiple interfaces
成角度。但是有一种方法可以使用(only in say)
进行多重继承TypeScript Mixins
。
带有downside
的唯一mixins
是您将必须define all the used base class methods in the child class
。 [注意-这不是实际的继承。基本上,您将所有基类属性添加到子类。 ]
此外,您将必须在代码中的某个位置declare
使用mixin
方法来完成所有繁重的工作。 (Preferrably the app.module to have global access)
。
PFB mixin
方法:
function applyMixins(derivedCtor: any, baseCtors: any[]) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
if (name !== 'constructor') {
derivedCtor.prototype[name] = baseCtor.prototype[name];
}
});
});
}
参考-https://www.stevefenton.co.uk/2014/02/TypeScript-Mixins-Part-One/
PFB ChildComponent
的代码段。我已经在您的mixin
本身中添加了ChildComponent
方法。您可以将它们放在代码中的任何位置。
export class ChildComponent {
propertyClass1: string;
propertyComp1:string;
sayHelloClass: (value) => void;
init: (value) => void;
sayHelloComponent: (value) => void;
constructor(private service: Service1Service) {
// super()
}
ngOnInit() {
this.applyMixins(ChildComponent, [MyCom1Component,MyClass1]);
this.sayHelloClass(this.propertyClass1);
this.init("hoohoho");
this.sayHelloClass(this.propertyClass1);
this.sayHelloComponent(this.propertyComp1);
}
applyMixins(derivedCtor: any, baseCtors: any[]) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
if (name !== 'constructor') {
derivedCtor.prototype[name] = baseCtor.prototype[name];
}
});
});
}
}
答案 2 :(得分:1)
您可以使用 Typescript mixins 来实现。 Angular Material在其项目中执行此操作,您可以检查其来源code
但是这种方法远非完美,因为它为您可能不需要的代码增加了很多样板和复杂性。 因此,如果可以避免,那就更好。
说,我已经为您的stackblitz项目添加了提到的此解决方案。
在您的代码中,您还尝试执行Typescript mixins,但是您似乎从未扩展MyCom1Component类,但是在下面的这段代码中, MyCom1Component充当变量名!而不是类!
const addMyClassOneInheritance = <T extends new(...args: any[]) => any>(MyCom1Component: T) => {
return class extends MyCom1Component /* THIS IS A VARIABLE NAME */ {
constructor(...args: any[]) {
super(...args);
}
};
};
在简历中,您使用此方法所要做的是在各个mixins中分离类逻辑,例如:
export function mixinMyCom1Component<T extends Constructor<{}>>(base: T): MyCom1ComponentCtor & T {
return class extends base {
propertyComp1 = "MyCom1";
constructor(...args: any[]) { super(...args); }
sayHelloComponent(value:string){console.log('component say'+ value)}
};
}
export function mixinMyClass1<T extends Constructor<{}>>(base: T): MyClass1Ctor & T {
return class extends base {
propertyClass1 = "MyClass1"
constructor(...args: any[]) { super(...args); }
init(value:string){
this.propertyClass1 = value;
}
sayHelloClass(value:string){console.log('class say'+ value)}
};
}
之后,您可以像这样编写ChildComponent:
export class ChildComponentBase {
constructor() {}
}
export const _ChildComponentMixinBase = mixinMyClass1(mixinMyCom1Component(ChildComponentBase));
@Component({...})
export class ChildComponent extends _ChildComponentMixinBase {
constructor(private service: Service1Service) {
super()
}
}
PD :请参见stackblitz示例,因为在此发布的代码中缺少一些正确实现所需的样板和类型。
希望这可以有所帮助!
答案 3 :(得分:0)
在Angular中这是不可能的,因为您不能在Javascript的一个类中扩展2个类,并且组件是一个类。
您应该寻找重用代码的另一种方式,就像Jose Guzman刚才说的那样。 也许创建服务