[removed] Setting Nested object value by ID

前端 未结 4 1144
日久生厌
日久生厌 2021-01-21 07:26

I would like to know what is the best way to update the member of the multilevel object collection in JavaScript

Here is the simplified version of my collection:

相关标签:
4条回答
  • 2021-01-21 08:01

    You can build a map of objects by id for direct access:

    var map = {};
    (function recurse(steps) {
        for (var i=0; i<steps.length; i++) {
            var step = steps[i];
            map[ step.id ] = step;
            if ("childSteps" in step)
                recurse(step.childSteps);
        }
    })(this.Steps);
    
    function updateObjectByID(id, string) {
        map[id].text = string;
    }
    

    A comment on your code: You overcomplified a lot. When the condition if(obj.id == objId) is met, you have your obj reference already!!! Now there is absolutely no need to search for a path to it, build a string from that, and eval it. Just assign directly to its property!

    function(steps, objId, value, whatParam, command) {
        if (typeof whatParam == 'undefined')
            whatParam = 'selected';
        $.each(steps, function(index, obj){
            if(obj.id == objId) {
                // removed a lot of unecessary stuff
    
                // not sure, looks like "value" was evaled sometimes as well
                obj[whatParam] = value;
    
             } // insert an "else" here if ids are unique
             if (typeof obj.childSteps != 'undefined') {           
                 this.setupObjectState(obj.childSteps, objId, value, whatParam, command);
             }
        });
    }
    
    0 讨论(0)
  • 2021-01-21 08:02

    You must recursively descend your tree structure searching for the object with the target "id" and replace its text. For example:

    function updateObjectByID(obj, id, text) {
      if (!obj) return;
      if (obj.id === id) {
        obj.text = text;
      } else if ((typeof(obj)==='object') && (obj.constructor===Array)) {
        for (var i=0; i<obj.length; i++) {
          updateObjectByID(obj[i], id, text);
        }
      } else if (obj.childSteps) {
        updateObjectByID(obj.childSteps, id, text);
      }
    }
    
    updateObjectByID(this.Steps, 11, 'String to be set');
    

    However, this solution can be optimized by tree pruning.

    0 讨论(0)
  • 2021-01-21 08:22

    Since you call updateObjectById() with an ID, the ID has to be unique. Why don´t you change your structure like this then:

    this.Steps = [
        { id: 1, text: "test" },
        { id: 2, parent: 1, text: "test" },
        { id: 3, parent: 1, text: "test" },
        { id: 4, parent: 1, text: "test" },
        { id: 10, parent: 4, text: "test" },
        { id: 11, parent: 4, text: "test" },
        { id: 5, parent: 1, text: "test"},
        { id: 6, parent: 1, text: "test"},
        { id: 7, parent: 1, text: "test"},    
        { id: 8, parent: 1, text: "test"},
        { id: 9, parent: 1, text: "test"}
    ]
    

    This way you can easily update your entries like this:

    function updateObjectByID(id, text) {
        for(var i = 0; i < this.Steps.length; i++) {
            if(this.Steps[i].id === id) {
                this.Steps[i].text = text;
                break;
            }
        }
    }
    

    With the extra attribute parent you can still easily get all the children of an element like this:

    function getChildrenByID(id) {
        var array = [];
        for(var i = 0; i < this.Steps.length; i++) {
            if(this.Steps[i].parent === id) {
                array.push(this.Steps[i]);
            }
        }
        return array;
    }
    
    0 讨论(0)
  • 2021-01-21 08:25
    function updateObjectByID(id, text) {
        (function setText(steps) {
            for(var i = 0; i < steps.length; i++){
                var step = steps[i];
                if(step.id === id){
                    step.text = text;
                }
                if ("childSteps" in step){
                    setText(step.childSteps);
                }
            }
        })(this.Steps);
    }
    

    Here is demo. http://jsfiddle.net/qDWX8/

    0 讨论(0)
提交回复
热议问题