更新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循环。
感谢您的反馈。
塔雷克