Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何创建向组件类添加单个函数的装饰器?_Javascript_Reactjs_Decorator_Ecmascript Next - Fatal编程技术网

Javascript 如何创建向组件类添加单个函数的装饰器?

Javascript 如何创建向组件类添加单个函数的装饰器?,javascript,reactjs,decorator,ecmascript-next,Javascript,Reactjs,Decorator,Ecmascript Next,首先,我应该说我对es7装饰师了解很少。基本上我想要的是一个名为@model的装饰器,它向名为model的组件添加一个函数。举个例子,我把它叫做 @model class FooBar extends Component { } 然后FooBar类现在将具有model函数 以下是我尝试过的: Model.js export default function reactModelFactory( ctx ){ return (key)=>{ return {

首先,我应该说我对es7装饰师了解很少。基本上我想要的是一个名为
@model
的装饰器,它向名为
model
的组件添加一个函数。举个例子,我把它叫做

@model class FooBar extends Component { }
然后FooBar类现在将具有model函数

以下是我尝试过的:

Model.js

export default function reactModelFactory( ctx ){

    return (key)=>{
        return {
            onChange: (e)=>ctx.setState({[key]:e.target.value}),
            value: ctx.state[key],
            name: key
        };
    };

};

function modelDecorator() {
    return function(ctx){
        return class extends ctx{
            constructor(...args){
                super(...args);
                this.model = reactModelFactory(this);
            }
        }
    }
}

export { modelDecorator as model };
import React,{PureComponent} from 'react';
import {model} from './Model';

@model class Login extends PureComponent{}
Login.js

export default function reactModelFactory( ctx ){

    return (key)=>{
        return {
            onChange: (e)=>ctx.setState({[key]:e.target.value}),
            value: ctx.state[key],
            name: key
        };
    };

};

function modelDecorator() {
    return function(ctx){
        return class extends ctx{
            constructor(...args){
                super(...args);
                this.model = reactModelFactory(this);
            }
        }
    }
}

export { modelDecorator as model };
import React,{PureComponent} from 'react';
import {model} from './Model';

@model class Login extends PureComponent{}
返回错误消息:

TypeError:超级表达式必须为null或函数,而不是对象


我不知道这意味着什么。我正在寻找一些帮助来让我的decorator工作,另外一个好处是完全理解decorators的概念。

您的模型decorator不应该返回新函数
ctx
将传递给
modelDecorator
本身。因此,您只需要从中返回新扩展的类:

function modelDecorator(ctx) {
  return class extends ctx {
    constructor(...args) {
      super(...args);
      this.model = reactModelFactory(this);
    }
  }
}
请注意,如果您的decorator应该像这样使用(角度样式decorators),那么您尝试的语法将起作用:

然后需要额外的闭包来将传递的参数保存到装饰器中:

function modelDecorator({ modelName }) {
  return (ctx) => {
    console.log('model name', modelName)
    return class extends ctx {
      constructor(...args) {
        super(...args);
        this.model = reactModelFactory(this);
      }
    }
  }
}
要添加到@dfsq的答案中(我假设它能满足您的要求),您可以在界面性能方面进一步,将
model()
添加到
原型中,而不是像这样添加到每个实例中:

export default function reactModelFactory() {
  return function model (key) {
    return {
      onChange: (e) => this.setState({ [key]: e.target.value }),
      value: this.state[key],
      name: key
    };
  };
};

function modelDecorator(Class) {
  Object.defineProperty(Class.prototype, 'model', {
    value: reactModelFactory(),
    configurable: true,
    writable: true
  });

  return Class;
}
这对于性能来说要好得多,因为它会导致装饰器使用
模型
成员方法一次性修改现有类的
原型
,而不是每次构造新实例时都在匿名扩展类的
构造函数
中附加
模型
方法的作用域副本

为了澄清,这意味着在@dfsq的回答中,
reactModelFactory()
在每次构造新实例时被调用,而在这个回答中,
reactModelFactory()
仅在类上激活装饰器时被调用一次

我在中使用
可配置
可写
的原因是
类{}
语法在
原型
上本机定义了成员方法:

类虚拟{
伪(){}
}
让{
可配置,
可写,
可枚举
}=Object.getOwnPropertyDescriptor(Dummy.prototype,“Dummy”);
console.log('configurable',configurable);
console.log('enumerable',enumerable);

console.log('writable',writable)仅供参考,这不是ES7,这是一个被拒绝的语法建议,所以据我所知,它依赖于一个不推荐的遗留巴贝尔转换。@帕特里克·罗伯茨认识帕特里克很好,谢谢你提供的信息。