Cuối cùng tôi đã chơi xung quanh với các nhà trang trí và quyết định ghi lại những gì tôi đã tìm ra cho bất cứ ai muốn tận dụng điều này trước khi bất kỳ tài liệu nào được đưa ra. Xin vui lòng chỉnh sửa này nếu bạn thấy bất kỳ sai lầm.
Điểm chung
- Trình trang trí được gọi khi lớp được khai báo không phải khi một đối tượng được khởi tạo.
- Nhiều trang trí có thể được định nghĩa trên cùng một Class / Thuộc tính / Phương thức / Tham số.
- Trang trí không được phép trên các nhà xây dựng.
Một trang trí hợp lệ nên là:
- Chỉ định cho một trong các loại Trang trí (
ClassDecorator | PropertyDecorator | MethodDecorator | ParameterDecorator
).
- Trả về một giá trị (trong trường hợp các trình trang trí lớp và trình trang trí phương thức) có thể gán cho giá trị được trang trí.
Tài liệu tham khảo
Phương pháp / Trang trí Accessor chính thức
Thông số thực hiện:
target
: Nguyên mẫu của lớp ( Object
).
propertyKey
: Tên của phương thức ( string
| symbol
).
descriptor
: A TypedPropertyDescriptor
- Nếu bạn không quen với các khóa của bộ mô tả, tôi khuyên bạn nên đọc về nó trong tài liệu này trên Object.defineProperty
(đó là tham số thứ ba).
Ví dụ - Không có đối số
Sử dụng:
class MyClass {
@log
myMethod(arg: string) {
return "Message -- " + arg;
}
}
Thực hiện:
function log(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) {
const originalMethod = descriptor.value; // save a reference to the original method
// NOTE: Do not use arrow syntax here. Use a function expression in
// order to use the correct value of `this` in this method (see notes below)
descriptor.value = function(...args: any[]) {
// pre
console.log("The method args are: " + JSON.stringify(args));
// run and store result
const result = originalMethod.apply(this, args);
// post
console.log("The return value is: " + result);
// return the result of the original method (or modify it before returning)
return result;
};
return descriptor;
}
Đầu vào:
new MyClass().myMethod("testing");
Đầu ra:
Phương thức lập luận là: ["tests"]
Giá trị trả về là: Tin nhắn - kiểm tra
Ghi chú:
- Không sử dụng cú pháp mũi tên khi đặt giá trị của bộ mô tả. Bối cảnh
this
sẽ không là ví dụ nếu bạn làm.
- Tốt hơn là sửa đổi bộ mô tả gốc hơn là ghi đè lên bộ mô tả hiện tại bằng cách trả về một bộ mô tả mới. Điều này cho phép bạn sử dụng nhiều trình trang trí chỉnh sửa mô tả mà không ghi đè lên những gì một trình trang trí khác đã làm. Làm điều này cho phép bạn sử dụng một cái gì đó giống
@enumerable(false)
và @log
cùng một lúc (Ví dụ: Xấu so với Tốt )
- Hữu ích : Đối số loại
TypedPropertyDescriptor
có thể được sử dụng để hạn chế chữ ký phương thức nào ( Ví dụ phương thức ) hoặc chữ ký của người truy cập ( Ví dụ về trình truy cập ) mà trình trang trí có thể được đưa vào.
Ví dụ - Với đối số (Nhà máy trang trí)
Khi sử dụng đối số, bạn phải khai báo một hàm với các tham số của trình trang trí, sau đó trả về một hàm có chữ ký của ví dụ mà không có đối số.
class MyClass {
@enumerable(false)
get prop() {
return true;
}
}
function enumerable(isEnumerable: boolean) {
return (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) => {
descriptor.enumerable = isEnumerable;
return descriptor;
};
}
Trang trí phương pháp tĩnh
Tương tự như một trình trang trí phương thức với một số khác biệt:
target
Tham số của nó là hàm xây dựng chính nó chứ không phải nguyên mẫu.
- Bộ mô tả được xác định trên hàm xây dựng chứ không phải nguyên mẫu.
Lớp trang trí
@isTestable
class MyClass {}
Thông số thực hiện:
target
: Lớp trang trí được khai báo trên ( TFunction extends Function
).
Ví dụ sử dụng : Sử dụng api siêu dữ liệu để lưu trữ thông tin trên một lớp.
Trang trí tài sản
class MyClass {
@serialize
name: string;
}
Thông số thực hiện:
target
: Nguyên mẫu của lớp ( Object
).
propertyKey
: Tên của tài sản ( string
| symbol
).
Ví dụ sử dụng : Tạo một trình @serialize("serializedName")
trang trí và thêm tên thuộc tính vào danh sách các thuộc tính để tuần tự hóa.
Trang trí tham số
class MyClass {
myMethod(@myDecorator myParameter: string) {}
}
Thông số thực hiện:
target
: Nguyên mẫu của lớp ( Function
dường như Function
không còn hoạt động nữa. Bạn nên sử dụng any
hoặc Object
ở đây ngay bây giờ để sử dụng trình trang trí trong bất kỳ lớp nào. Hoặc chỉ định (các) loại lớp bạn muốn hạn chế)
propertyKey
: Tên của phương thức ( string
| symbol
).
parameterIndex
: Chỉ mục của tham số trong danh sách các tham số của hàm ( number
).
Ví dụ đơn giản
Ví dụ chi tiết
@Injectable
vào trang trí, hãy tham khảo