[Angular のデコレータ] - クラス デコレータ (クラス デコレータ)

クラスに作用するデコレータはクラス デコレータであり、デコレータ入門の        デコレータの最後の例は  クラス デコレータです。

1. コンストラクターのクラス デコレーターを変更する必要がある

1.1. パラメータなしのデコレータ

デコレーターの紹介        で 最後に示したのは 、コンストラクターを変更するデコレーターです。

function changePrice<T extends { new(...args: any[]): {} }>(constructor: T) {
    return class extends constructor {
        price = 666;
    };
}
 
@changePrice
export class Grape {
    price: number = 0;
    constructor(price: number) {
        this.price = price;
        console.log(`constructor price : ${this.price}`);
    }
}
 
//组件中调用代码
let grape = new Grape(4);
console.log(grape);

        操作結果:

 1.2. パラメータ付きのデコレータ

        変更に基づいて、受信パラメーターのクラス デコレーターを実装できます。

function changePrice<T extends { new(...args: any[]): {} }>(price: number) {
    return (constructor: T) => {
        let newConstruct = function (...args: any[]) {
            let c = class extends constructor {
                price = price;
            };
            return new c(args);
        }
        let func: any = function (...args: any[]) {
            return newConstruct(args);
        }
        return func;
    };
}
 
@changePrice(8)
export class Grape {
    price: number = 0;
    constructor(price: number) {
        this.price = price;
        console.log(`constructor price : ${this.price}`);
    }
}
 
@changePrice(10)
export class Banana {
    price: number = 0;
    constructor(price: number) {
        this.price = price;
        console.log(`constructor price : ${this.price}`);
    }
}
 
//组件中调用代码
let grape = new Grape(4);
console.log(grape);
let banana = new Banana(4);
console.log(banana);

        デコレータ パラメータ と実行結果を介して値を渡すことにより、価格 フィールドを変更します。

         もちろん、デコレータでクラスに新しいフィールドを追加することもできます:

function changePrice<T extends { new(...args: any[]): {} }>(price: number) {
    console.log("price decorator define");
    return (constructor: T) => {
        console.log("price decorator");
        let newConstruct = function (...args: any[]) {
            let c = class extends constructor {
                price = price;
            };
            console.log("set price");
            return new c(args);
        }
        let func: any = function (...args: any[]) {
            return newConstruct(args);
        }
        return func;
    };
}

function color<T extends { new(...args: any[]): {} }>(color: string) {
    console.log("color decorator define");
    return (constructor: T) => {
        console.log("color decorator");
        let newConstruct = function (...args: any[]) {
            let c = class extends constructor {
                color = color;
            };
            console.log("set color");
            return new c(args);
        }
        let func: any = function (...args: any[]) {
            return newConstruct(args);
        }
        return func;
    };
}

@color("purple")
@changePrice(8)
export class Grape {
    price: number = 0;
    constructor(price: number) {
        this.price = price;
        console.log(`constructor price : ${this.price}`);
    }
}

//组件中调用代码
let grape = new Grape(4);
console.log(grape);
let grape2 = new Grape(5);
console.log(grape2);

        The above code adds a new decorator  color , which modified the constructor of the target class and adds a color field. 上記のコードはまた、デコレータの順序を分析するためにいくつかのプリントを追加します。操作結果:

        最後の印刷時にオブジェクトにcolorフィールドが追加されていることがわかります.追加の印刷を通じて、構築メソッド ( newConstruct )の外側の印刷が1 回だけ印刷されていることがわかります。クラスが変換され、構築メソッド内の印刷 ( newConstruct ) が新しいオブジェクトごとに実行されますデコレータの適用順序は、外側から内側の順番に対応して、上から下への書き込み順に実行されます. 上記のコードは次のように理解できます: 

@color("purple")
(
    @changePrice(8)
    class Grape{ ... }
)

        したがって、上記の印刷順序になります。

2. コンストラクターのクラスデコレーターを変更する必要はありません

2.1. パラメータなしのデコレータ

        クラスのコンストラクターを拡張および変更する必要がない場合は、より簡潔なエンコード形式を使用できます。

function enableBuy(target: Function): void {
    target.prototype.buy = function (count: number) {
        console.log(`need money : ${this.price * count} to buy ${count}`);
    }
}

@color("purple")
@changePrice(8)
@enableBuy
export class Grape {
    price: number = 0;
    constructor(price: number) {
        this.price = price;
        console.log(`constructor price : ${this.price}`);
    }
}
 
//组件中调用代码
let grape: any = new Grape(4);
console.log(grape);
grape.buy(10);

        コードを実行すると、次のように出力されます。

2.2. パラメータ付きのデコレータ

        パラメータを渡した後にエンコード形式を追加します。 

function enableBuy(coupon:number) {   //coupon 打折金额
    return (target: Function) => {
        target.prototype.buy = function (count: number) {
            console.log(`need money ${this.price * count - coupon} to buy ${count}`);  
        }
    }
}

@color("purple")
@changePrice(8)
@enableBuy(5)
export class Grape {
    price: number = 0;
    constructor(price: number) {
        this.price = price;
        console.log(`constructor price : ${this.price}`);
    }
}

//组件中调用代码
let grape: any = new Grape(4);
console.log(grape);
grape.buy(10);

        コードを実行すると、次のように出力されます。

         ここではクラスデコレータの使い方を紹介しますので、意見交換を歓迎します。

おすすめ

転載: blog.csdn.net/evanyanglibo/article/details/122579784