手动实现angular注解

371 阅读1分钟

angular注解又叫装饰器,其实质是一个返回了函数的函数,即它的返回值就是一个函数,注解虽然是angular提供的,但是其实际使用的是js的特性

1、应用于类内部的属性的注解

// emoji.ts
// 将属性值两边分别加上表情符号
export function Emoji() {
// 注解就是返回了一个函数的函数
//target代表类,key代表类中的属性名
	return (target: any, key: string) => {
		let val = target[key];
		const getter = () => {
			return val;
		}
		const setter = (value: string) => {
			val = `🤣${value}🤣`;
		}
		Object.defineProperty(target, key, {
		// 重新定义属性的getter、setter方法
			get: getter,
			set: setter,
			enumerable: true,
			configurable: true,
		});
	}
}
// test.component.ts
import { Emoji } from './Emoji.ts';
export class TestComponent {
	@Emoji() result = 'Hello';
}
// test.component.html
//此时在浏览器上渲染出来的就是🤣Hello🤣
<div>{{result}}</div>

1、应用于类内部的方法的注解

// confirmable.ts
export function Confirmable(message: string) {
    // 属性描述符:PropertyDescriptor,包含configurable,enumerable,writable
    // 属性描述符中的属性控制这对象的一些功能特性
    return (target: object, key: string, descriptor: PropertyDescriptor) => {
    	  // 先把原来的方法值存储起来
        const original = descriptor.value;
        // args代表原方法中传入的参数
        descriptor.value = function(...args: any) {
            // window.confirm()弹出对话框
            // allow为用户点击后的结果
            const allow = window.confirm(message); 
            if (allow) {
                const result = original.apply(this, args);
                return result;
            }
            return null;
        }
        return descriptor;
    }
}
// test.component.ts
import { Confirmable } from "./confirmable.ts";
export class TestComponent {
  // 应用于类内方法的注解
  @Confirmable('您确认要执行吗?')
  handleClick() {
    console.log('点击已执行');
  }
}
// test.component.html
// 此时点击hello, world!就会弹出一个对话框,点击‘确认’,才会执行handleClick()
<div class="test" (click)="handleClick()">{{hello, world!}}</div>