ModelTreeMaker.js (4686B)
1 /** 2 * Creates a tree of nodes for a given model 3 */ 4 Ext.define("PartKeepr.ModelTreeMaker.ModelTreeMaker", { 5 /** 6 * @var {Array} Contains the models already in the field tree 7 */ 8 visitedModels: [], 9 10 /** 11 * @var {Array} Field names which should be ignored. 12 */ 13 ignoreFields: [], 14 15 customFieldIgnorer: Ext.emptyFn, 16 17 constructor: function () 18 { 19 this.visitedModels = []; 20 }, 21 22 /** 23 * Adds a field to be ignored. 24 * 25 * @param {String} field The field to be ignored. 26 */ 27 addIgnoreField: function (field) 28 { 29 this.ignoreFields.push(field); 30 }, 31 setCustomFieldIgnorer: function (customIgnorer) 32 { 33 this.customFieldIgnorer = customIgnorer; 34 }, 35 /** 36 * Builds the field tree recursively. Handles infinite recursions (e.g. in trees). 37 * 38 * @param {Ext.data.NodeInterface} node The current node 39 * @param {Ext.data.Model} model The model 40 * @param {String} prefix The prefix. Omit if first called 41 * @param {Function} callback The calback, optional 42 */ 43 make: function (node, model, prefix, callback) 44 { 45 var newNode,i ,j, childNode, associationAlreadyProcessed; 46 47 if (!prefix) { 48 prefix = ""; 49 } 50 51 if (!callback) { 52 callback = null; 53 } 54 55 var fields = model.getFields(); 56 57 this.visitedModels.push(model.getName()); 58 59 for (i = 0; i < fields.length; i++) { 60 if (fields[i]["reference"] === null) { 61 // Field is a scalar field 62 if (this.ignoreFields.indexOf(fields[i].name) === -1 && !this.customFieldIgnorer(fields[i])) { 63 64 newNode = node.appendChild(Ext.create("PartKeepr.Data.ReflectionFieldTreeModel", { 65 text: fields[i].name, 66 leaf: true, 67 data: { 68 name: prefix + fields[i].name, 69 type: "field" 70 }, 71 entityIndex: "" 72 })); 73 74 if (callback) { 75 newNode.set(callback(fields[i], newNode)); 76 } 77 } 78 } else { 79 // Field is an association; recurse into associations 80 associationAlreadyProcessed = false; 81 for (j = 0; j < this.visitedModels.length; j++) { 82 if (this.visitedModels[j] === fields[i].reference.cls.getName()) { 83 // The association was already processed; skip return 84 associationAlreadyProcessed = true; 85 } 86 } 87 88 if (!associationAlreadyProcessed) { 89 childNode = node.appendChild(Ext.create("PartKeepr.Data.ReflectionFieldTreeModel", { 90 text: fields[i].name, 91 data: { 92 name: prefix + fields[i].name, 93 type: "manytoone" 94 }, 95 leaf: false 96 })); 97 98 if (callback) { 99 childNode.set(callback(fields[i], childNode)); 100 } 101 102 this.make(childNode, fields[i].reference.cls, prefix + fields[i].name + ".", callback); 103 } 104 } 105 } 106 107 var associations = model.associations; 108 109 110 for (i in associations) { 111 associationAlreadyProcessed = false; 112 if (typeof(associations[i].storeName) !== "undefined" && associations[i].isMany === true) { 113 for (j = 0; j < this.visitedModels.length; j++) { 114 if (this.visitedModels[j] === associations[i].type) { 115 associationAlreadyProcessed = true; 116 } 117 } 118 119 if (!associationAlreadyProcessed) { 120 childNode = node.appendChild(Ext.create("PartKeepr.Data.ReflectionFieldTreeModel",{ 121 text: associations[i].role, 122 data: { 123 name: prefix + associations[i].role, 124 type: "onetomany", 125 reference: associations[i].cls 126 }, 127 leaf: false 128 })); 129 130 if (callback) { 131 childNode.set(callback(associations[i].cls, childNode)); 132 } 133 134 this.make(childNode, associations[i].cls, prefix + associations[i].role+ ".", callback); 135 } 136 } 137 } 138 } 139 });