5 decorator typescript angular
我有使用主机绑定装饰器的组件来显示组件选择器,以便它们获取所有可用宽度:
@HostBinding('style.width.%')
@HostBinding('style.height.%')
private readonly SIZE = 100;
@HostBinding('style.display')
private readonly DISPLAY = 'block';
@HostBinding('style.box-sizing')
private readonly BOX_MODEL = 'border-box';
Run Code Online (Sandbox Code Playgroud)
我想要做的是创建一个单独的装饰器(在类或属性级别,我不在乎),包括所有这些,所以我不必每次都重写它.
现在,我通过创建一个超类并让我的其他类扩展它来使它工作,但它有很多限制和不便,因此我的问题.
任何帮助,即使它的文档,非常感谢!
编辑我也发现了这个SOF问题,但与我的问题的区别在于变量有一个值,我似乎无法找到如何将这些值传递给我的装饰器.
编辑2解释我的需要:我有这个组件
@Component(...)
export class MyAngularComponent extends HostBinderComponent {...}
Run Code Online (Sandbox Code Playgroud)
还有这个
export class HostBinderComponent {
@HostBinding('style.width.%')
@HostBinding('style.height.%')
private readonly SIZE = 100;
@boxComponent()
private readonly DISPLAY;
@HostBinding('style.box-sizing')
private readonly BOX_MODEL = 'border-box';
}
Run Code Online (Sandbox Code Playgroud)
我的最终目标是删除超类,并有类似的东西
@Component(...)
@BoxComponent()
export class MyAngularComponent {...}
Run Code Online (Sandbox Code Playgroud)
所以我不必再使用extends或HostBinding在我的Angular组件中了!
应用装饰器涉及调用__decorate辅助函数。该函数可以由编译器生成,也可以从自定义 tslib 中使用。Angular 使用 tehtslib模块来实现该__decorate功能,我们可以__decorate从那里使用 the 。(我们可以复制 ts 生成的版本或编写我们自己的__decorate调用装饰器函数的更简单版本,但最好只使用与框架使用的调用装饰器相同的方式)
有了这个函数(并且在检查 TS 如何调用字段的装饰器之后),我们可以轻松创建我们自己的复合装饰器:
import { __decorate } from 'tslib';
function BoxHostBindings() {
return function(target) {
__decorate([
HostBinding('style.width.%'),
HostBinding('style.height.%'),
], target.prototype, "SIZE", void 0);
__decorate([
HostBinding('style.display'),
], target.prototype, "DISPLAY", void 0);
__decorate([
HostBinding('style.box-sizing'),
], target.prototype, "BOX_MODEL", void 0);
}
}
Run Code Online (Sandbox Code Playgroud)
注意:我还没有对此进行广泛的测试,但它似乎有效,并且我希望它能够有效。
用法:
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
@BoxHostBindings()
export class AppComponent {
title = 'testapp';
private readonly SIZE = 100;
private readonly DISPLAY = 'block'
private readonly BOX_MODEL = 'border-box';
}
Run Code Online (Sandbox Code Playgroud)
编辑
设置属性值有点困难。我们无法轻松访问构造函数的执行,因此我们无法执行此操作。
一种选择是定义 上的值prototype,因为这些值是只读的,这应该可以正常工作:
function BoxHostBindings(size: number, display: string, box_model: string) {
return function(target) {
target.prototype.SIZE = size;
target.prototype.DISPLAY = display;
target.prototype.BOX_MODEL = box_model;
__decorate([
HostBinding('style.width.%'),
HostBinding('style.height.%'),
], target.prototype, "SIZE", void 0);
__decorate([
HostBinding('style.display'),
], target.prototype, "DISPLAY", void 0);
__decorate([
HostBinding('style.box-sizing'),
], target.prototype, "BOX_MODEL", void 0);
}
}
Run Code Online (Sandbox Code Playgroud)
我们还可以定义属性以允许用户修改值,并将其存储在字段('_' + name)中,但如果值未定义则返回默认值:
function BoxHostBindings(size: number, display: string, box_model: string) {
return function(target) {
function propHelper(name: string, defaultValue: any) {
Object.defineProperty(target.prototype, name, {
get: function () {
return this['_' + name] || defaultValue;
},
set: function(value: any ) {
this['_' + name] = value
},
enumerable: true,
configurable: true
});
}
propHelper("SIZE", size);
propHelper("DISPLAY", display);
propHelper("BOX_MODEL", box_model);
__decorate([
HostBinding('style.width.%'),
HostBinding('style.height.%'),
], target.prototype, "SIZE", void 0);
__decorate([
HostBinding('style.display'),
], target.prototype, "DISPLAY", void 0);
__decorate([
HostBinding('style.box-sizing'),
], target.prototype, "BOX_MODEL", void 0);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
78 次 |
| 最近记录: |