Typescript 装饰器如何用于 html 标签?
How can Typescript decorators be used for html labels?
我很难理解如何使用 Typescript decorators
。我有这个代码:
class Address {
private street: string;
private city: string;
private state: string;
private zipCode: string;
@displayName("Street")
get streetHtml() { return this.street; }
@displayName("City")
get cityHtml() { return this.city; }
@displayName("State")
get stateHtml() { return this.state; }
@displayName("Zip Code")
get zipCodeHtml() { return this.zipCode; }
public static map(input: any) {
let address = new Address();
address.street = input.street;
address.city = input.city;
address.state = input.state;
address.zipCode = input.zipCode;
return address;
}
}
function displayName(name: string) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
let label: HTMLLabelElement = document.createElement('label');
label.innerHTML = name;
return label;
};
}
var address = Address.map({ street: "123 My St", city: "Boise", state: "ID", zipCode: "83709" })
console.log(address.cityHtml);
然而,它唯一做的就是返回 "Boise"。我如何获得装饰器的东西?我确实在 tsconfig
.
中启用了 "experimentalDecorators": true
正如@JohnWhite 所评论的那样,class return 中的 getter 是一个字符串(由编译器从 return 类型推断出来),但是装饰器是要求更改 return a HTMLLabelElement
.
这可能会在编译时给您带来困难,或导致运行时错误。
话虽如此,回答你的问题:
您在装饰器中 return 不是访问器的 returned 值,因为 docs say:
If the accessor decorator returns a value, it will be used as the
Property Descriptor for the member
您需要做的是更改 "Property Descriptor" 使其 return 成为您想要的值:
function displayName(name: string) {
return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
descriptor.get = () => {
let label: HTMLLabelElement = document.createElement('label');
label.innerHTML = name;
return label;
}
};
}
编辑
发布我的答案后,我注意到您想要获得:
<label>Boise</label>
但是你是如何尝试实现它的(以及我的回答)returns:
<label>City</label>
为了获得所需的结果,我们需要稍微更改一下我的代码:
function displayName(name: string) {
return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
descriptor.get = function() {
let label: HTMLLabelElement = document.createElement('label');
label.innerHTML = this[name.toLowerCase()];
return label;
}
};
}
变化在哪里:
- return 函数现在是常规匿名函数而不是箭头函数,因此
this
将指向 class 实例而不是 window。
- 内部标签 html 现在是
this[name.toLowerCase()]
而不是 name
我很难理解如何使用 Typescript decorators
。我有这个代码:
class Address {
private street: string;
private city: string;
private state: string;
private zipCode: string;
@displayName("Street")
get streetHtml() { return this.street; }
@displayName("City")
get cityHtml() { return this.city; }
@displayName("State")
get stateHtml() { return this.state; }
@displayName("Zip Code")
get zipCodeHtml() { return this.zipCode; }
public static map(input: any) {
let address = new Address();
address.street = input.street;
address.city = input.city;
address.state = input.state;
address.zipCode = input.zipCode;
return address;
}
}
function displayName(name: string) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
let label: HTMLLabelElement = document.createElement('label');
label.innerHTML = name;
return label;
};
}
var address = Address.map({ street: "123 My St", city: "Boise", state: "ID", zipCode: "83709" })
console.log(address.cityHtml);
然而,它唯一做的就是返回 "Boise"。我如何获得装饰器的东西?我确实在 tsconfig
.
"experimentalDecorators": true
正如@JohnWhite 所评论的那样,class return 中的 getter 是一个字符串(由编译器从 return 类型推断出来),但是装饰器是要求更改 return a HTMLLabelElement
.
这可能会在编译时给您带来困难,或导致运行时错误。
话虽如此,回答你的问题:
您在装饰器中 return 不是访问器的 returned 值,因为 docs say:
If the accessor decorator returns a value, it will be used as the Property Descriptor for the member
您需要做的是更改 "Property Descriptor" 使其 return 成为您想要的值:
function displayName(name: string) {
return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
descriptor.get = () => {
let label: HTMLLabelElement = document.createElement('label');
label.innerHTML = name;
return label;
}
};
}
编辑
发布我的答案后,我注意到您想要获得:
<label>Boise</label>
但是你是如何尝试实现它的(以及我的回答)returns:
<label>City</label>
为了获得所需的结果,我们需要稍微更改一下我的代码:
function displayName(name: string) {
return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
descriptor.get = function() {
let label: HTMLLabelElement = document.createElement('label');
label.innerHTML = this[name.toLowerCase()];
return label;
}
};
}
变化在哪里:
- return 函数现在是常规匿名函数而不是箭头函数,因此
this
将指向 class 实例而不是 window。 - 内部标签 html 现在是
this[name.toLowerCase()]
而不是name