Как написать методы действия mobx в отдельных файлах и импортировать их в реальный класс mobx, имеющий наблюдаемые переменные? - PullRequest
0 голосов
/ 05 апреля 2019

У меня есть класс mobx, в котором есть наблюдаемая переменная с именем dataObject.Эта наблюдаемая переменная является объектом и имеет следующую структуру:

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

У каждого свойства объекта есть метод действия для его обновления.Например,

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

1 Ответ

0 голосов
/ 08 апреля 2019

Создайте интерфейс для объекта, который вы хотите в качестве наблюдаемого, и добавьте сигнатуру индекса.

Это выглядит примерно так:

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 этому действию.

У меня также естьотметил, что атрибуты any определенно должны быть некоторого типа, если остальная часть объекта имеет строгие типизации.Если у вас будет any типов в вашем объекте, вы также можете создать интерфейс, подобный interface IAny { [key: string]: any; }, и использовать его везде.

Я надеюсь, что это может помочь, и еще раз прошу прощения за пробелв ответах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...