【问题标题】:How to rewrite this js class without decorators如何在没有装饰器的情况下重写这个 js 类
【发布时间】:2018-12-17 23:41:11
【问题描述】:

我想在不使用装饰器的情况下使用 mobx。通常我使用 mobx 包中的decorate,但在这种特殊情况下,我找不到让它工作的方法。

原始代码:

import { observable } from 'mobx'
import { create, persist } from 'mobx-persist'

class Order {
  @persist('object')
  @observable
  currentOrder = null
}

我尝试了什么:

import { observable, decorate } from 'mobx'
import { create, persist } from 'mobx-persist'
import { compose } from 'recompose'

class Order {
  currentOrder = null
}

decorate(Order, {
    currentOrder: compose(persist('object'), observable),
})

错误来自persist 告诉serializr 装饰器没有正确使用。 知道为什么这与上面的不同并且不起作用吗?

【问题讨论】:

    标签: javascript decorator mobx mobx-persist


    【解决方案1】:

    TL;DR

    属性装饰器需要非常具体的组合实现。

    解决方案演示:

    完整答案

    属性装饰器基本上是以下形式的函数:
    (target, prop, descriptor) => modifiedDescriptor

    因此,为了组合两个属性装饰器,您需要将 第一个装饰器的结果作为 第二个装饰器的第三个参数(连同target和prop)。

    Recompose.compose(与lodash.flowRight相同)从右到左应用函数并将结果作为单个参数传递给下一个函数。

    因此,您不能使用Recompose.compose 来编写装饰器,但您可以轻松地为装饰器创建编写器:

    /* compose.js */
    
    export default (...decorators) => (target, key, descriptor) =>
      decorators.reduce(
        (accDescriptor, decorator) => decorator(target, key, accDescriptor),
        descriptor
      );
    

    然后我们使用它来编写observable 和persist("object")。

    /* Order.js */
    
    import { observable, decorate, action } from "mobx";
    import { persist } from "mobx-persist";
    import compose from "./compose";
    
    class Order {
      currentOrder = null;
    }
    
    export default decorate(Order, {
      currentOrder: compose(
        observable,
        persist("object")
      )
    });
    

    [21/8/18] MobX >=4.3.2 和 >=5.0.4 更新:

    我为 MobX5 和 MobX4 打开了 PR(已合并),以便在 decorate 实用程序函数中支持多个装饰器 OOB。
    所以,这在 MobX >=4.3.2 & >= 5.0.4 中可用:

    import { decorate, observable } from 'mobx'
    import { serializable, primitive } from 'serializr'
    import persist from 'mobx-persist';
    
    class Todo {
        id = Math.random();
        title = "";
        finished = false;
    }
    decorate(Todo, {
        title: [serializable(primitive), persist('object'), observable],
        finished: observable
    })
    

    【讨论】:

      【解决方案2】:

      一个更简单的解决方案是拥有

      class Stuff {
         title = ''
         object = {
            key: value
         }
      }
      
      decorate(Todo, {
          title: [persist, observable],
          object: [persist('object'),observable]
      })
      
      

      无需安装 serializr 包。以上功能内置于 mobx persist。

      【讨论】:

        猜你喜欢
        • 2016-03-24
        • 2017-05-29
        • 2022-01-08
        • 1970-01-01
        • 2015-05-20
        • 1970-01-01
        • 1970-01-01
        • 2015-11-17
        • 2023-02-07
        相关资源
        最近更新 更多