如何在单独的文件中编写mobx动作方法并将它们导入到具有可观察变量的实际mobx类中?

问题描述 投票:0回答:1

我有一个mobx类,它有一个名为dataObject的可观察变量。这个可观察变量是一个对象,它的结构是:

{
   name:string;
   dataType:string;
   value: string;
   description:string;
   .
   .
   .
   .
   . 
   ..... total around 45 such properties
}

每个object属性都有一个操作方法来更新它。例如

@action updateName = (name:string) =>{
   this.dataObject.name = name;
}

很难在同一类中维护所有这些45种动作方法。有没有办法在单独的ts文件中编写这些方法并将它们导入当前文件?

编辑:添加一部分dataObject接口及其几个操作方法

interface IDataObject{
    name:string;
    dataType:string;
    value:any;
    valueType:VALUE_TYPE|any;
    hasCustomValueType:boolean;
    customValueType:string|undefined;
    description:string;
    isRegistered:boolean;
    associatedVariableDetails:IVariableDetails[];
    hasMultipleValues:boolean;
    associatedService:SERVICE;
}

enum VALUE_TYPE{
    MAJOR = 'major',
    MED = 'med',
    MINOR = 'minor'
}

enum SERVICE{
    PUSH_IN = 'pushin',
    PULL_OUT = 'pullout'
}

interface IVariableDetails{
    variableName:string;
    varirbleDataType:string;
    variableValue:any;
    hasArray:boolean;
    isDeletable:boolean;    
}

//////////////
method to update dataType
@action updateDataType = (dataType:string) =>{
    this.dataObject.dataType = dataType;
    if(dataType === 'string'){
        this.dataObject.value = ''
    }
    else if(dataType === 'boolean'){
        this.dataObject.value = false
    }
    else if(dataType === 'integer'){
        this.dataObject.value = 0
    }
}


methods to modify associatedVariableDetails

@action addVariableDetails = (variableDetails:IVariableDetails) =>{
    this.dataObject.associatedVariableDetails.push(variableDetails);
}

@action updateMultipleValueState = (hasMultipleValues:boolean) =>{
    this.dataObject.hasMultipleValues = hasMultipleValues;
    if(!hasMultipleValues){
        this.dataObject.associatedVariableDetails = this.dataObject.associatedVariableDetails[0];
    }
}
reactjs typescript mobx mobx-react
1个回答
0
投票

为您想要的对象创建一个接口作为observable并添加索引签名。

这看起来像这样:

interface foo {
  [key: string]: type;
  bar: string;
}

然后将密钥传递给更新操作并更新值,如object[key] = newValue

例:

    @action update = (key: string, value: type) => {
      object[key] = value;
    }

这将允许您使用一个函数将任何值修补到您的可观察对象中。

这篇文章深入解释了索引签名:https://basarat.gitbooks.io/typescript/docs/types/index-signatures.html

尽管如此,回答你原来的问题。您可以创建45个函数并将它们全部导出到对象中并将它们导入到此文件中,但是如果类型或字段发生更改,则该解决方案可能过于繁琐且难以维护。如果此解决方案不起作用,我可以展示一个示例。我上面解释的解决方案是处理对象补丁的更有效方法。

编辑:

我为编辑答案的延迟道歉。我已经对上面的代码进行了编辑,显示了我将采用这种对象的方法。这是编辑:

interface IDataObject{
    [key: string]: string | boolean | VALUE_TYPE | SERVICE | IVariableDetails[];
    name: string;
    dataType: string;
    value: any; // THIS SHOULD BE STRICTLY DEFINED
    valueType: VALUE_TYPE|any; // THIS SHOULD ALSO BE STRICTLY DEFINED
    hasCustomValueType: boolean;
    customValueType?: string;
    description: string;
    isRegistered:boolean;
    associatedVariableDetails: IVariableDetails[];
    hasMultipleValues: boolean;
    associatedService: SERVICE;
}

enum VALUE_TYPE{
    MAJOR = 'major',
    MED = 'med',
    MINOR = 'minor'
}

enum SERVICE{
    PUSH_IN = 'pushin',
    PULL_OUT = 'pullout'
}

interface IVariableDetails{
    variableName:string;
    varirbleDataType:string;
    variableValue:any;
    hasArray:boolean;
    isDeletable:boolean;    
}

@action updateField = (key: string, value: string | boolean | VALUE_TYPE | SERVICE) => {
    this.dataObject[key] = value;
}
@action addVariableDetails = (variableDetails: IVariableDetails) => {
    this.dataObject.associatedVariableDetails.push(variableDetails);
}
@action updateMultipleValueState = (hasMultipleValues: boolean) => {
    this.dataObject.hasMultipleValues = hasMultipleValues;
    if(!hasMultipleValues){
        this.dataObject.associatedVariableDetails = this.dataObject.associatedVariableDetails[0];
    }
}

我在这里做的是暴露了一种方法来操纵半原始值,之后不需要额外的工作,他们只想要新的值。然后我会根据你需要对你的对象做的工作类型,根据需要创建更复杂的@actions。如图所示,updateField动作不允许你将它与VariableDetails类型的参数一起使用,如果你尝试向该动作发送一个variableDetails参数,那么这将使得typescript抱怨。

我还注意到,如果对象的其余部分具有严格的类型,那么any属性肯定应该是某种类型。如果您要在对象中使用any类型,您可以创建一个像interface IAny { [key: string]: any; }这样的界面并在任何地方使用它。

我希望这可以有所帮助,我再次为答复中的差距道歉。

© www.soinside.com 2019 - 2024. All rights reserved.