我有一个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];
}
}
为您想要的对象创建一个接口作为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; }
这样的界面并在任何地方使用它。
我希望这可以有所帮助,我再次为答复中的差距道歉。