-
目录
-
TypeScript官方文档
-
前言
本文用到的是Decorators
-
需求
紧跟前一篇,公司要求解析前一个数据和后一个数据操作的比较,基本上已经实现的需求。
但是通过上一篇文章我们可以知道,KV中文显示前端效果是写死的,当然也可以写成配置文件,放到assert去请求,但是公司说了要利用注解的方式,我思考了一下毕竟我是做后台JAVA的,所以我立刻想到了自定义注解的关键点。
但是又考虑到如果一个class中又包含了多个class,也就是说这个数据不仅仅包括了自己本身的简单数据,还有一些通过ID关联的其他数据。
这就表示数据是多层次的JSON结构,这样的话不好比较【参考例子JAVA自定义注解@FileName】,我的做法是将多层次的JSON只看成一层,就算是对象A里面的对象B某一个属性发生了变化,依旧B全部返回,然后通过前端解析,将对象中的对象B单拎出来,上一次的操作和这次update操作比较,B自己和B自己比反而更加简单了。
但是与此同时需要将写死的KV变成可方便变化的,利用我JAVA后台开发的思想,我觉得TypeScript也有相应的@FileName("用户名称"),读取注解属性解释的功能,于是我找到了reflect-metadata【文档请点击】
-
操作【原生注解】
- jar安装 【npm i reflect-metadata --save】
- demo【干货】
@Component({
selector: 'app-dashboard-v1',
templateUrl: './v1.component.html',
})
export class DashboardV1Component implements OnInit {
constructor(private http: HttpClient) {
}
ngOnInit(): void {
console.log('↓↓♚♚♚♚♚♚♚♚♚♚♚♚♚♚♚♚♚♚↓↓');
console.log(Reflect.getMetadata('Person', Person));
console.log(Reflect.getMetadata('a', new Person, 'message'));
console.log('↑↑♚♚♚♚♚♚♚♚♚♚♚♚♚♚♚♚♚♚↑↑');
}
}
import 'reflect-metadata';
@Reflect.metadata('Person', '类名')
class Person {
@Reflect.metadata('a', '短信信息')
message: string;
}
3.结果
-
自定义注解
-
例子1
对于类解释的自定义注解,随便取一个名字:ClassDecorators
import { Component, OnInit } from '@angular/core'; import 'reflect-metadata'; @Component({ selector: 'app-dashboard-v1', templateUrl: './v1.component.html', }) export class DashboardV1Component implements OnInit { ngOnInit(): void { var p = new Person(); let value: string = Reflect.getMetadata('ClassDecorators', p.constructor); console.log(value); } } function ClassDecorators(value: string) { return function(target: Function) { Reflect.defineMetadata('ClassDecorators', value, target); }; } @ClassDecorators('这里是类解释:如用户信息') class Person { } 结果
-
例子2
对于类属性解释的前缀注解,随便取一个名字:ClassDecorators
import { Component, OnInit } from '@angular/core'; import 'reflect-metadata'; @Component({ selector: 'app-dashboard-v1', templateUrl: './v1.component.html', }) export class DashboardV1Component implements OnInit { ngOnInit(): void { const p = new Person(); p.message = 'world'; // 获取元数据前缀,key,当前对象,message属性 const prefix = Reflect.getMetadata(formatMetaDataKey, new Person(), 'message'); console.log(prefix + p.message); } } // 声明唯一的元数据key const formatMetaDataKey = Symbol('format'); // 前缀注解 function prefix(target: string) { // 根据key将前缀存至元数据中 return Reflect.metadata(formatMetaDataKey, target); } class Person { @prefix('hello, ') message: string; } 结果:
-
例子3【重点】
有前缀注释和类注释和属性注释
import { Component, OnInit } from '@angular/core';
import 'reflect-metadata';
// 声明唯一的元数据key
const formatMetaDataKey = Symbol('format');
// 前缀注解
function prefix(target: string) {
// 根据key将前缀存至元数据中
return Reflect.metadata(formatMetaDataKey, target);
}
function ClassDecorators(value: string) {
return function(target: Function) {
Reflect.defineMetadata('ClassDecorators', value, target);
};
}
@Component({
selector: 'app-dashboard-v1',
templateUrl: './v1.component.html',
})
export class DashboardV1Component implements OnInit {
ngOnInit(): void {
const p = new Person();
p.message = 'world';
// 获取元数据前缀,key,当前对象,message属性 下面p可以用 'new Person()' 代替
const prefix = Reflect.getMetadata(formatMetaDataKey, p, 'message');
console.log(prefix + p.message); // hello, world
console.log(Reflect.getMetadata('ClassDecorators', p.constructor)); // 这里是类解释:如用户信息
console.log(Reflect.getMetadata('Person', p, 'message'));// 短信信息
}
}
@ClassDecorators('这里是类解释:如用户信息')
class Person {
@prefix('hello, ')
@Reflect.metadata('Person', '短信信息')
message: string;
}
结果:
-
参考案例