javascript / AngularJS性能上的JSON对象结构

时间:2017-10-11 22:16:12

标签: angularjs performance

更新1:添加用于处理两种结构的源代码:单层和双层。

更新2: 代码有问题。它已在此处确定并修复:

https://stackoverflow.com/a/46738836/4180447

塔雷克。

我注意到如果我有一个具有以下结构的JSON对象:

{
    "$structureOpt": "twolayers",
    "subform_0": {
        "age_range_property2": [{
            "maxlen": 25,
            "required": true,
            "readonly": false
        }],
        "age_range_property": [{
            "maxlen": 25,
            "required": true,
            "readonly": false
        }],
        "appraiser_address": [{
            "maxlen": 100,
            "required": true,
            "readonly": false
        }],
        "appraiser_city": [{
            "maxlen": 50,
            "required": true,
            "readonly": false
        }],
        "appraiser_company": [{
            "maxlen": 100,
            "required": true,
            "readonly": false
        }],
        "appraiser_email": [{
            "maxlen": 80,
            "required": true,
            "readonly": false
        }],
        "appraiser_name": [{
            "maxlen": 100,
            "required": true,
            "readonly": false
        }],
        "appraiser_phone": [{
            "maxlen": 30,
            "required": true,
            "readonly": false
        }],
        "appraiser_postal_code": [{
            "maxlen": 15,
            "required": true,
            "readonly": false
        }],
        "appraiser_province": [{
            "maxlen": 20,
            "required": true,
            "readonly": false
        }],
        "appr_address1": [{
            "maxlen": 100,
            "required": false,
            "readonly": false
        }],
        "assessment_date": [{
            "maxlen": 30,
            "required": true,
            "readonly": false
        }],
        "built_up_other": [{
            "maxlen": 50,
            "required": false,
            "readonly": false
        }],
        "purpose_of_appraisal": "",
        "intended_use": "",
        "report_representable_to": "",
        "property_rights_appraised": "",
        "physical_partial_holding": "",
        "highbestuse_vacant": "",
        "highbestuse_asimproved": "",
        "trend_of_district": "",
        "built_up": "",
        "confirmity_age": "",
        "condition": "",
        "size": "",
        "market_supply": "",
        "existing_use_zoning": "",
        "electrical": "",
        "landscaping": "",
        "curb_appeal": "",
        "adverse_influence": "",
        "nrating": ""
    },
    "subform_1": {
        "asbestos": [{
            "maxlen": 1,
            "required": false,
            "readonly": false
        }],
        "basement_area": [{
            "maxlen": 100,
            "required": true,
            "readonly": false
        }],
        "basement_finishes_utility_01": [{
            "maxlen": 500,
            "required": false,
            "readonly": false
        }],
        "basement_finish": [{
            "maxlen": 100,
            "required": false,
            "readonly": false
        }],
        "basement_finish_01": [{
            "maxlen": 100,
            "required": false,
            "readonly": false
        }],
        "basement_finish_02": [{
            "maxlen": 25,
            "required": false,
            "readonly": false
        }],
        "basement_finish_03": [{
            "maxlen": 25,
            "required": false,
            "readonly": false
        }],
        "bathrooms_07": [{
            "maxlen": 10,
            "required": false,
            "readonly": false
        }],
        "bathrooms_08": [{
            "maxlen": 10,
            "required": false,
            "readonly": false
        }],
        "bathrooms_09": [{
            "maxlen": 15,
            "required": false,
            "readonly": false
        }],
        "bathrooms_10": [{
            "maxlen": 20,
            "required": false,
            "readonly": false
        }],
        "bathrooms_11": [{
            "maxlen": 10,
            "required": false,
            "readonly": false
        }],
        "bathrooms_12": [{
            "maxlen": 20,
            "required": false,
            "readonly": false
        }],
        "bedrooms_01": [{
            "maxlen": 10,
            "required": false,
            "readonly": false
        }],
        "bedrooms_02": [{
            "maxlen": 10,
            "required": false,
            "readonly": false
        }]
    },
    "subform_24": {
        "image_addendum3_description_line1": [{
            "maxlen": 150,
            "required": false,
            "readonly": false
        }],
        "image_addendum3_description_line2": [{
            "maxlen": 150,
            "required": false,
            "readonly": false
        }]
    },
    "subform_27": {
        "addendum_comments_4": [{
            "maxlen": 15000,
            "required": false,
            "readonly": false
        }]
    },
    "subform_28": {
        "addendum_comments_5": [{
            "maxlen": 15000,
            "required": false,
            "readonly": false
        }]
    }
}

...需要2个嵌套的for循环来处理,我注意到与以下结构相比,上面的结构更快(具有更好的性能):

{
    "$structureOpt": "onelayer",
    "age_range_property2": [{
        "maxlen": 25,
        "required": true,
        "readonly": false
    }],
    "age_range_property": [{
        "maxlen": 25,
        "required": true,
        "readonly": false
    }],
    "appraiser_address": [{
        "maxlen": 100,
        "required": true,
        "readonly": false
    }],
    "appraiser_city": [{
        "maxlen": 50,
        "required": true,
        "readonly": false
    }],
    "appraiser_company": [{
        "maxlen": 100,
        "required": true,
        "readonly": false
    }],
    "appraiser_email": [{
        "maxlen": 80,
        "required": true,
        "readonly": false
    }],
    "appraiser_name": [{
        "maxlen": 100,
        "required": true,
        "readonly": false
    }],
    "appraiser_phone": [{
        "maxlen": 30,
        "required": true,
        "readonly": false
    }]
    ..
    ..
    ..
}

"子表单的总数" items为28,字段总数为1300 +。

当我使用一个图层时,该过程需要10秒钟才能完成。当我使用两层(使用" subform_xx")时,完成时间减少了10秒。这与我的预期相反。

知道我的发现是否正确?

在使用两个图层的情况下,我使用了两个for循环,在使用一个图层的情况下,我使用了一个for循环。其他一切都是一样的。我期望使用一个for循环应该更好。

我已经开发了处理验证规则所需的函数的更新版本,以确保公共代码部分是相同的。请参阅以下代码:

var getChildren = function(el, doInterpolate) {
    var resultChildren;
    doInterpolate = (doInterpolate===undefined)?true:doInterpolate;
    //Return list of elements which were not compiled before 'compiled === undefined'
    resultChildren = $(':input', el);
    //If required, use $interpolate to get the final result for each ID...
    if (doInterpolate) {
        for (var i=0; i < resultChildren.length; i++) {
            if (resultChildren[i].id) {
                resultChildren[i].id = $interpolate(resultChildren[i].id)(scope);
            }
        }
    }
    return resultChildren;
}

function doApplyValidation(scope, el, attrs, ngForm) {
    var children;
    var fieldValidList;
    var validationStructOpt;
    //Do run interpolation of elements IDs u
    children = getChildren(el, true);
    // Or, do not run interpolation of elements IDs
    //children = resultChildren = $(':input', el); //getChildren(el, false); 
    mainElmID = $interpolate(el[0].id)(scope);
    validationList=formView.getRequiredField();
    //Get 'validationStructOpt' option:
    //      Option = 'onelayer' means there is no 'subform' layer
    //      Option = 'twolayers' means there is a 'subform' layer which is the default
    validationStructOpt = validationList.$structureOpt || 'twolayers';
    if (validationStructOpt === 'onelayer') {
        //for (var fldIdx=0; fldIdx < Object.keys(validationList).length; fldIdx++) {
        console.log("One layer. Number of rules: ", Object.keys(validationList).length)
        for (var fldIdx=0; fldIdx < children.length; fldIdx++) {
            var childElm;
            var child;
            var childID;
            var validObjects;
            var elmScope;
            var elmModel;
            //childID = Object.keys(validationList)[fldIdx];
            //if (childID.startsWith('$')) {
            //  continue;
            //}
            //childElm = children.filter('#'+childID);
            //child = childElm.get(0);
            childElm = children.eq(fldIdx);
            child = childElm.get(0);
            child.id = $interpolate(child.id)(scope);
            childID = child.id;
            //if (childElm.length) {
            if (childID && (childID in validationList)) {
                //Validation rule for 'childID': related element was found, and now will apply validation rule.
                validObjects = validationList[childID];
                elmScope = angular.element(child).scope() || scope;
                elmModel = angular.element(child).controller('ngModel');
                applyValidationElement(childID, child, childElm, elmScope, elmModel, validationList);
            }
        }
    } else 
    if (validationStructOpt === 'twolayers') {
        for (var subformIdx=0; subformIdx < Object.keys(validationList).length; subformIdx++) {
            var keySubform = Object.keys(validationList)[subformIdx];
            if (keySubform.startsWith('$')) {
                continue;
            }
            var subform = validationList[keySubform];
            var lastFieldID;
            for (var childIdx=0; childIdx < Object.keys(subform).length; childIdx++) {
                var childID = Object.keys(subform)[childIdx];
                var validObjects;
                var childElm;
                var child;
                var elmScope;
                var elmModel;
                childElm = children.filter('#'+childID);
                //console.log(mainElmID, childID);
                if (childElm.length) {
                    //Validation rule for 'childID': related element was found, and now will apply validation rule.
                    validObjects = subform[childID];
                    child = childElm.get(0);
                    elmScope = angular.element(child).scope() || scope;
                    elmModel = angular.element(child).controller('ngModel');
                    applyValidationElement(childID, child, childElm, elmScope, elmModel, validationList[keySubform]);
                }
            }
        }
    }
    //After done processing all elements under 'el', compile the parent element 'el'.
    $compile(el, null, 100)(scope);
    //If saved flag value is true, enable back validation
    if (saveIsValidationRequired) {
        scope.startExecValidations();
    }
}

如您所见,如果validationStructOpt$structureOpt,上面的代码会根据结构选项onelayer(或twolayers)来处理所需的正确处理。您将看到它与完全相同的代码,除非结构为twolayers,它使用两个for循环。

感谢您的反馈。

塔雷克

0 个答案:

没有答案