如何使用属性的值作为另一个属性的默认值?

时间:2021-08-12 18:37:20

I have a mongoose schema and I would like to use the value of a property as default value for another property, something like:

我有一个mongoose模式,我想使用属性的值作为另一个属性的默认值,如:

schemaDef = { 
    myProperty: {type: String, required: true}
    ...
    otherProperty: {type: String, default: this.myProperty}
}

I thought it was possible but apparently is not, could someone confirm that and possibly give me a reference?

我认为这是可能的,但显然不是,有人可以确认,并可能给我一个参考?

1 个解决方案

#1


1  

Though there's no built in way, you could write a few helper functions to behave it like you want. An example schema:

虽然没有内置方法,但您可以编写一些辅助函数来表现它,就像您想要的那样。示例模式:

module.exports = function(){
    var schemaDef = {
        email : {type : String, required: true},
        secondaryEmail : {type : String, required: true, selfDefault: "email"},
        fullName : {type : String, required: true, selfDefault: {fields: ["firstName","middleName", "lastName"], space: true}},
        password: {type: String, required: true},
        firstName : {type : String, required: true},
        middleName : {type : String, required: true},
        lastName : {type : String, required: true}
    };
    var selfDefaults = initSelfDefaults(schemaDef);
    var UserSchema = new Schema(schemaDef);
    UserSchema.pre('validate', function(next) {
        setSelfDefaults(this, selfDefaults)
        next();
    });
    return mongoose.model("User", UserSchema);
};

You can place the following helper functions in other files to require and use them for all models/schemas:

您可以将以下辅助函数放在其他文件中以要求并将它们用于所有模型/模式:

// gets and returns all selfDefaults from the scehmaDef obj. Throws error if selfDefault reference is invalid
function initSelfDefaults(schemaDef){
    var defaults = {};
    for(var key in schemaDef){
        if(schemaDef[key].selfDefault){
            if(schemaDef[key].selfDefault.fields){
                schemaDef[key].selfDefault.fields.forEach(function(field){
                    if (!schemaDef[field]){
                        throw new Error(field + " is an invalid selfDefault reference")
                    }
                })
            }
            else if(!schemaDef[schemaDef[key].selfDefault]){
                throw new Error(schemaDef[key].selfDefault + " is an invalid selfDefault reference")
            }
            defaults[key] = schemaDef[key].selfDefault;
            delete schemaDef[key].selfDefault;
        }
    };
    return defaults
}

// sets the selfDefaults for the fields of the document being created if the fields are empty
function setSelfDefaults(doc, defaults){
    for(var key in defaults){
        if(!doc[key]){
            if(defaults[key].fields){
                var fields = [];
                for(var i=0; i<defaults[key].fields.length; i++){
                    if(doc[defaults[key].fields[i]]){
                        fields.push(doc[defaults[key].fields[i]])
                    }
                }
                doc[key] = defaults[key].space? fields.join(" ") : fields.join("");  
            }
            else{
                doc[key] = doc[defaults[key]];
            }
        }
    }
    return;
}

It doesn't work for nested schemas, but you can tweak the code to make it so.

它不适用于嵌套模式,但您可以调整代码来实现它。

#1


1  

Though there's no built in way, you could write a few helper functions to behave it like you want. An example schema:

虽然没有内置方法,但您可以编写一些辅助函数来表现它,就像您想要的那样。示例模式:

module.exports = function(){
    var schemaDef = {
        email : {type : String, required: true},
        secondaryEmail : {type : String, required: true, selfDefault: "email"},
        fullName : {type : String, required: true, selfDefault: {fields: ["firstName","middleName", "lastName"], space: true}},
        password: {type: String, required: true},
        firstName : {type : String, required: true},
        middleName : {type : String, required: true},
        lastName : {type : String, required: true}
    };
    var selfDefaults = initSelfDefaults(schemaDef);
    var UserSchema = new Schema(schemaDef);
    UserSchema.pre('validate', function(next) {
        setSelfDefaults(this, selfDefaults)
        next();
    });
    return mongoose.model("User", UserSchema);
};

You can place the following helper functions in other files to require and use them for all models/schemas:

您可以将以下辅助函数放在其他文件中以要求并将它们用于所有模型/模式:

// gets and returns all selfDefaults from the scehmaDef obj. Throws error if selfDefault reference is invalid
function initSelfDefaults(schemaDef){
    var defaults = {};
    for(var key in schemaDef){
        if(schemaDef[key].selfDefault){
            if(schemaDef[key].selfDefault.fields){
                schemaDef[key].selfDefault.fields.forEach(function(field){
                    if (!schemaDef[field]){
                        throw new Error(field + " is an invalid selfDefault reference")
                    }
                })
            }
            else if(!schemaDef[schemaDef[key].selfDefault]){
                throw new Error(schemaDef[key].selfDefault + " is an invalid selfDefault reference")
            }
            defaults[key] = schemaDef[key].selfDefault;
            delete schemaDef[key].selfDefault;
        }
    };
    return defaults
}

// sets the selfDefaults for the fields of the document being created if the fields are empty
function setSelfDefaults(doc, defaults){
    for(var key in defaults){
        if(!doc[key]){
            if(defaults[key].fields){
                var fields = [];
                for(var i=0; i<defaults[key].fields.length; i++){
                    if(doc[defaults[key].fields[i]]){
                        fields.push(doc[defaults[key].fields[i]])
                    }
                }
                doc[key] = defaults[key].space? fields.join(" ") : fields.join("");  
            }
            else{
                doc[key] = doc[defaults[key]];
            }
        }
    }
    return;
}

It doesn't work for nested schemas, but you can tweak the code to make it so.

它不适用于嵌套模式,但您可以调整代码来实现它。