加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

angular – 将多个主机绑定组合到一个装饰器中

发布时间:2020-12-17 17:37:23 所属栏目:安全 来源:网络整理
导读:我有使用主机绑定装饰器的组件来显示组件选择器,以便它们获取所有可用宽度: @HostBinding('style.width.%')@HostBinding('style.height.%')private readonly SIZE = 100;@HostBinding('style.display')private readonly DISPLAY = 'block';@HostBinding('st
我有使用主机绑定装饰器的组件来显示组件选择器,以便它们获取所有可用宽度:

@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';

我想要做的是创建一个单独的装饰器(在类或属性级别,我不在乎),包括所有这些,所以我不必每次都重写它.

现在,我通过创建一个超类并让我的其他类扩展它来使它工作,但它有很多限制和不便,因此我的问题.

任何帮助,即使它的文档,非常感谢!

编辑我也找到了this SOF question,但与我的问题不同的是变量有一个值,我似乎无法找到如何将这些值传递给我的装饰器.

编辑2解释我的需要:我有这个组件

@Component(...)
export class MyAngularComponent extends HostBinderComponent {...}

还有这个

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';
}

我的最终目标是删除超类,并有类似的东西

@Component(...)
@BoxComponent()
export class MyAngularComponent {...}

所以我不再需要在我的Angular组件中使用extends或HostBinding了!

解决方法

应用装饰器涉及调用__decorate辅助函数.此函数既可以由编译器生成,也可以从自定义tslib中使用. Angular使用teh tslib模块作为__decorate函数,我们可以从那里使用__decorate. (我们可以复制版本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'),"DISPLAY",void 0);
    __decorate([
      HostBinding('style.box-sizing'),"BOX_MODEL",void 0);
  }
}

注意:我没有对此进行过广泛的测试,但似乎有效,我希望它能够正常工作.

用法:

@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';
}

编辑

设置属性的值有点困难.我们无法轻松访问构造函数执行,因此我们无法执行此操作.

一种选择是在原型上定义值,因为值是只读的,这应该可以正常工作:

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.%'),void 0);
  }
}

我们还可以定义属性以允许用户修改值,并将其存储在字段(‘_’名称)中,但如果值未定义则返回默认值:

function BoxHostBindings(size: number,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.%'),void 0);
  }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读