在属性装饰器中获取属性类实例

时间:2018-08-26 23:02:41

标签: typescript typescript-decorator

我正在尝试编写一个@Prop装饰器来帮助我设置自定义元素属性。

这是我要实现的代码:

class MyClass extends HtmlElement {
   get text() {
     return this.getAttribute('text')
   }

   set text(newVal){
     this.setAttribute('text', newVal)
   }

   connectedCallback() {
     this.innerHTML = `<div>${this.text}</div>`
   }
}

这是带有装饰器的类

class MyClass extends HtmlElement {
   @Prop() text: string;

   connectedCallback() {
     this.innerHTML = `<div>${this.text}</div>`
   }
}

这是装饰器功能

const Prop = () => (target : any, key : string) => {
    const getter = () => target.getAttribute(key);
    const setter = (newVal) => target.setAttribute(key, newVal);

    if (!delete this[key]) return;
    Object.defineProperty(target, key, {
        get: getter,
        set: setter
    });
}

但是无论何时调用getter函数,我都会收到此错误:

Uncaught TypeError: Illegal invocation
    at HTMLElement.getter (app.js:16)

检出app.js:16会显示以下代码:

const getter = () => target.getAttribute(key);

带下划线的target.getAttribute(key);

2 个答案:

答案 0 :(得分:0)

要定义getter和setter方法,请不要删除属性,然后重新添加它,但要使用属性描述符

sklearn

https://www.typescriptlang.org/docs/handbook/decorators.html

答案 1 :(得分:0)

以类作为目标而不是类的实例来调用装饰器。该类的实例将以this的形式出现在getter / setter函数中。这就是为什么在这里使用箭头功能不是一个好主意的原因,因为它们从声明站点捕获this。在这种情况下,使用常规功能最有效。

const Prop = () => (target: any, key: string, descriptor: PropertyDescriptor) => {
    const getter = function (this: HTMLElement) {
        return this.getAttribute(key);
    }
    const setter = function (this: HTMLElement, newVal) {
        this.setAttribute(key, newVal);
    }
    descriptor = descriptor || {};
    descriptor.get = getter;
    descriptor.set = setter;
    return descriptor;
}

class MyClass extends HTMLElement {
    @Prop() text: string;

    connectedCallback() {
        this.innerHTML = `<div>${this.text}</div>`
    }
}