[Decorator in Angular] - パラメータ デコレータ (パラメータ デコレータ)

        パラメータ デコレータは、パラメータ宣言の前に宣言されます。パラメーター デコレーターは、クラス コンストラクターまたはメソッドによって宣言された関数に適用されます。

        パラメータ デコレータは、次の 3 つのパラメータを受け入れます。

        target: Object - 装飾されるクラス

        propertyKey: string | symbol - メソッド名

        parameterIndex: number - メソッド内のパラメーターのインデックス値

        パラメーター デコレーターは通常、メソッド デコレーターと組み合わせて使用​​され、いくつかの特別な機能を実現します。

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

        次のコードは、パラメーター デコレーターを使用して、メソッドの入力パラメーターに対して null 以外のチェックを実行する方法を示しています。

export class User {
    
    @validate
    say(@required sth: string) {
        console.log(`user say: ${sth}`);
    }
}

//组件中调用
let user = new User();
user.say("");
user.say("hi");

        実行中の印刷物:

プログラムは、必要なデコレーター         で追加されたパラメーターの非 null 値をチェックし、受信パラメーターが空の文字列の場合にエラー メッセージを出力することがわかります。ここでは、検証機能を実現するために、検証ツール クラスを追加します。

export class Validator {
    private static requiredMap: Map<any, Map<string, any>> = new Map();
    
    static registerRequired(target: any, methodName: string, paramIndex: number) {
        let targetMap = this.requiredMap.get(target);
        if (!targetMap) {
            targetMap = new Map();
            this.requiredMap.set(target, targetMap);
        }
        let methodMap = targetMap.get(methodName);
        if (!methodMap) {
            methodMap = new Map();
            targetMap.set(methodName, methodMap);
        }
        methodMap.set(paramIndex, true);
    }

    static validateRequired(target: any, methodName: string, paramValues: any[]): boolean {
        let targetMap = this.requiredMap.get(target);
        if (!targetMap) return true;
        let methodMap = targetMap.get(methodName);
        if (!methodMap) return true;
        for (const [index, paramValue] of paramValues.entries()) {
            let required = methodMap.get(index);
            if (!!required) {
                if (typeof paramValue === 'undefined' || paramValue === null || paramValue === "") {
                    console.error(`param at index ${index} for method ${methodName} must have non-null value.`);
                    return false;
                }
            }
        }
        return true;
    }
}

        このうち、registerRequired メソッドは検証が必要なメソッドパラメーター情報の登録に使用され、validateRequired メソッドはメソッドパラメーターの検証に使用されます。

        必要なパラメータデコレータのコードに検証情報を登録します

function required(target: any, propertyKey: string, parameterIndex: number) {
    Validator.registerRequired(target, propertyKey, parameterIndex);
}

検証メソッド デコレーターのコード        で検証メソッドを呼び出します

function validate(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    let originalMethod = descriptor.value;
    descriptor.value = function (...args: any[]) {
        if (!Validator.validateRequired(target, propertyKey, args)) {
            return;
        }
        return originalMethod.apply(this, args);
    }
}

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

        もちろん、パラメータ デコレータはパラメータを渡すこともできます。上記のコードは、メソッド パラメータの正規表現の検証を満たすように変更されています。

        変更された User クラス:

export class User {
    name: string = "";
    mail: string = "";

    @validate
    say(@required sth: string) {
        console.log(`user say: ${sth}`);
    }

    @validate
    setInfo(@reg('^[A-Za-z0-9]+$') name: string, @reg('^[A-Za-z0-9]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$') mail: string) {
        this.name = name;
        this.mail = mail;
        console.log(`name: ${this.name}, mail: ${this.mail}`);
    }
}

        setInfoメソッドは、名前を入力できる英字と数字のみに制限し、メールをメールボックスの形式に合わせて制限します。

        検証ツール クラスを変更し、正規表現の登録および検証メソッドを追加します。

private static regMap: Map<any, Map<string, any>> = new Map();

static registerReg(target: any, methodName: string, paramIndex: number, pattern: string) {
        let targetMap = this.regMap.get(target);
        if (!targetMap) {
            targetMap = new Map();
            this.regMap.set(target, targetMap);
        }
        let methodMap = targetMap.get(methodName);
        if (!methodMap) {
            methodMap = new Map();
            targetMap.set(methodName, methodMap);
        }
        methodMap.set(paramIndex, pattern);
    }
    
    static validateReg(target: any, methodName: string, paramValues: any[]): boolean {
        let targetMap = this.regMap.get(target);
        if (!targetMap) return true;
        let methodMap = targetMap.get(methodName);
        if (!methodMap) return true;
        for (const [index, paramValue] of paramValues.entries()) {
            let pattern = methodMap.get(index);
            if (!!pattern) {
                let pass = new RegExp(pattern).test(paramValue);
                if (!pass) {
                    console.error(`param at index ${index} for method ${methodName} does not match regular expression.\nwanted: ${pattern}\npassed value: ${paramValue}`);
                    return false;
                }
            }
        }
        return true;
    }

        Regパラメータ デコレータ コード:

function reg(pattern: string) {
    return function (target: any, propertyKey: string, parameterIndex: number) {
        Validator.registerReg(target, propertyKey, parameterIndex, pattern);
    }
}

        validate メソッド デコレーターのコードを変更して、正規表現の検証を追加します。

function validate(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    let originalMethod = descriptor.value;
    descriptor.value = function (...args: any[]) {
        if (!Validator.validateRequired(target, propertyKey, args)) {
            return;
        }
        if (!Validator.validateReg(target, propertyKey, args)) {
            return;
        }
        return originalMethod.apply(this, args);
    }
}

        コンポーネント内の呼び出しコード:

    let user = new User();
    user.say("");
    user.say("hi");
    user.setInfo("..", "dd");
    user.setInfo("abc1", "dd");
    user.setInfo("1", "[email protected]");

        実行中の印刷物:

         メソッド デコレータと組み合わせて正規表現を指定するパラメータ デコレータは、メソッドのパラメータの正規表現一致をチェックし、一致規則を満たさないパラメータはメソッドを呼び出さないことがわかります。

3. 複数のパラメーター デコレーターによるパラメーターの装飾

        もちろん、同じパラメータは複数のデコレータの追加をサポートします. say メソッドを変更して、 requiredデコレータと regデコレータを同時にパラメータに追加します . regデコレータは、shit を含む文字列の受け渡しを制限します.これは、禁止された文字列に相当します. コードを変更します次のように:

    @validate
    say(@required @reg('^(?!.*?shit).*$') sth: string) {
        console.log(`user say: ${sth}`);
    }

        コンポーネント内の呼び出しコード:

    let user = new User();
    user.say("");
    user.say("shit");
    user.say("hi");

        実行中の印刷物:

        目的の効果が得られていることがわかります。

        上記のプログラムの動作を分析すると、パラメーターデコレーターのコードはコンパイル時に実行され、メソッドデコレーターのコードはメソッドが呼び出されるたびに実行されることがわかります。

        ここではパラメータ デコレータの使用法を紹介します。意見交換を歓迎します。

おすすめ

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