将Typescript装饰器作为mixin?
我正在用Angular2写一个大的应用程序。我有一个基类可以这样做:将Typescript装饰器作为mixin?,typescript,angular,Typescript,Angular,我正在用Angular2写一个大的应用程序。我有一个基类可以这样做: export abstract class ReactiveComponent implements OnInit, OnDestroy, AfterViewInit { abstract ngOnInit(): void; protected _subscriptions: Rx.Subscription[] = []; private __viewInit = new Rx.Subject<v
export abstract class ReactiveComponent implements OnInit, OnDestroy, AfterViewInit {
abstract ngOnInit(): void;
protected _subscriptions: Rx.Subscription[] = [];
private __viewInit = new Rx.Subject<void>();
protected _viewInit: Rx.Observable<void> = this.__viewInit;
ngOnDestroy() {
if (this._subscriptions)
this._subscriptions.forEach(s => s.unsubscribe());
}
ngAfterViewInit() {
this.__viewInit.complete();
}
}
导出抽象类ReactiveComponent实现OnInit、OnDestroy和AfterViewInit{
抽象ngOnInit():void;
受保护的订阅:Rx.Subscription[]=[];
private _viewInit=new Rx.Subject();
受保护的viewInit:Rx.Observable=this.viewInit;
恩贡德斯特罗(){
如果(此订阅)
此.u subscriptions.forEach(s=>s.unsubscribe());
}
ngAfterViewInit(){
这是.u viewInit.complete();
}
}
但是我的一些类需要有其他的基类,我遇到了经典的mixin/继承砖墙
所以我想把它变成一个装饰器,因为Angular2不关心这些方法来自哪里,我可以很容易地做一个constructor.prototype.ngondestory=…
对吗?
这给我留下了两个问题:
这个
@ContentChildren(…)something代码>通过mixin的属性?如何在constructor.prototype.something
上动态定义装饰器?我对“特质”的理解是错误的吗
虽然mixin是实际的类,但可以将它们作为接口继承:
class MixinA {
public a(): void { console.log("A"); }
}
class MixinB {
public b(): void { console.log("B"); }
}
class MyClass implements MixinA, MixinB {
public a: () => void;
public b: () => void;
}
applyMixins(MyClass, [MixinA, MixinB]);
其中关键字为实现
作为一般的OO原则,接口是公共契约,它们不处理实际的实现,而实际的实现是受保护的功能领域
(2) 如果我理解正确,当你说“动态定义装饰器”
时,那么是的,这与官方文档中的示例类似,因此你应该能够执行类似(未测试的):
const numbersmatakey=Symbol(“数字”);
类型生产者=()=>数量;
减速器类型=(上一个:编号,当前:编号)=>编号;
函数编号(…道具:数组){
返回Reflect.metadata(numberMetadataKey,props);
}
函数getNumbers(目标:MyClass,propertyKey:string){
让arr:Array=Reflect.getMetadata(numbersMetadataKey、target、propertyKey);
返回arr.map(item=>typeof item===“number”?item:item());
}
函数编号工厂(最小:编号=0,最大:编号=100):编号{
返回Math.random()*(max-min)+min;
}
类MyClass{
@数字(numberFactory(),numberFactory.bind(null,50200))
私人减速机:减速机;
建造师(减速器:减速器){
这个减速机=减速机;
}
reduce():数字{
let numbers:number[]=getNumbers(这是“减速机”);
返回数字.reduce(这个.reducer);
}
}
新建MyClass((上一个,当前)=>上一个+当前).reduce();
新建MyClass((上一个,当前)=>上一个*当前).reduce();
我只想补充一点,有时候多重继承是必需的,而且是不可避免的,如果支持的话(这里是用mixin实现的),但在其他时候,对多重继承的需要只是指向一个不充分的设计。是的,我实际上不想要多重继承,我想要的是“Traits”或“AOP”或者不管我们称之为什么,这些daysmixin都是特性,这就是在typescript中实现多重继承的方式。我的观点是,虽然有时这是最好的方法,但在其他情况下,您可以更改设计并使用普通继承,这在大多数情况下更容易。在任何情况下,我都展示了如何使用mixin来完成您要完成的任务。好吧,我将尝试找到一种不需要那些受保护成员的方法。。。我其余的需求都能通过混合得到充分满足。至于(2),一旦我完全理解了你的例子的作用,我可能会有更多的问题
const numbersMetadataKey = Symbol("numbers");
type Producer = () => number;
type Reducer = (previous: number, current: number) => number;
function numbers(...props: Array<number | Producer>) {
return Reflect.metadata(numbersMetadataKey, props);
}
function getNumbers(target: MyClass, propertyKey: string) {
let arr: Array<number | Producer> = Reflect.getMetadata(numbersMetadataKey, target, propertyKey);
return arr.map(item => typeof item === "number" ? item : item());
}
function numberFactory(min: number = 0, max: number = 100): number {
return Math.random() * (max - min) + min;
}
class MyClass {
@numbers(numberFactory(), numberFactory.bind(null, 50, 200))
private reducer: Reducer;
constructor(reducer: Reducer) {
this.reducer = reducer;
}
reduce(): number {
let numbers: number[] = getNumbers(this, "reducer");
return numbers.reduce(this.reducer);
}
}
new MyClass((previous, current) => previous + current).reduce();
new MyClass((previous, current) => previous * current).reduce();