admin管理员组

文章数量:1384595

I have tree of javascript objects. Let's call it "family. It can contain any number of certain objects ("parents") which can each contain any number of "child" objects. The number of levels in this structure is known and each level of the tree only contains objects of one certain type.

All the objects have data and methods.

I want to save the structured data in the databese. JSON.stringify() does it perfect extracting the data and also saving the structure. But how to get back to objects? JSON.parse() fails, because it recreates the object without methods.

What should I do in this case? Should I write my own function for recreating the object from string? Or should I save the data together with methods somehow (seems a waste).

As I know the structure, it would be very handy if there would be a possibility to point to an object and tell "that's a parent object" and it would get the methods. I could easily cycle through it then. But I don't know how to that and I'm also afraid that my constructors could set some values to the default ones.

The objects constructors would look something like this:

function lines()
{
    this.lines = [];
    this.height = 0.5*theMargin;

    this.addLine = addLine;

    function addLine(newline)
    {
        this.lines.push(newline);
        this.height += newline.height;
    }
}

function aLine()
{
    this.dots = [];
    this.height = 0;
    this.length = indent;

    this.insertDot = insertDot;

    function insertDot(pos,newDot)
    {
        this.dots.splice(pos,0,newDot);
        this.length += newDot.length;
        this.height = Math.max(this.height,newDot.height);
        if (this.length > maxLineLength)
        { "I will not go into details here" }
    }
}

Then I would do like:

var a = new lines();
var testline = new aLine();
var testdot = new aDot();

testdot.height = 10;
testdot.length = 15;
testline.insertDot(0,testdot);
a.addLine(testline);
a.addLine(testline);

Then I want to save the data about lengths and heights. And the structure, to know which dot belongs in which line.

I send that data to the webserver. I think these are the key lines to understand the used approach:

post = "name=" + name + "&tab=" + JSON.stringify(file);
req.open("POST", "saveFile.php", true);
req.send(post);

The saved file saves exactly what I wanted - the structure and data. But I don't know how to make it bee an object again. I am not insisting to use JSON.stringify() method. I would enjoy any approach that would let me save the content without repeatedly saving the methods.

I have tree of javascript objects. Let's call it "family. It can contain any number of certain objects ("parents") which can each contain any number of "child" objects. The number of levels in this structure is known and each level of the tree only contains objects of one certain type.

All the objects have data and methods.

I want to save the structured data in the databese. JSON.stringify() does it perfect extracting the data and also saving the structure. But how to get back to objects? JSON.parse() fails, because it recreates the object without methods.

What should I do in this case? Should I write my own function for recreating the object from string? Or should I save the data together with methods somehow (seems a waste).

As I know the structure, it would be very handy if there would be a possibility to point to an object and tell "that's a parent object" and it would get the methods. I could easily cycle through it then. But I don't know how to that and I'm also afraid that my constructors could set some values to the default ones.

The objects constructors would look something like this:

function lines()
{
    this.lines = [];
    this.height = 0.5*theMargin;

    this.addLine = addLine;

    function addLine(newline)
    {
        this.lines.push(newline);
        this.height += newline.height;
    }
}

function aLine()
{
    this.dots = [];
    this.height = 0;
    this.length = indent;

    this.insertDot = insertDot;

    function insertDot(pos,newDot)
    {
        this.dots.splice(pos,0,newDot);
        this.length += newDot.length;
        this.height = Math.max(this.height,newDot.height);
        if (this.length > maxLineLength)
        { "I will not go into details here" }
    }
}

Then I would do like:

var a = new lines();
var testline = new aLine();
var testdot = new aDot();

testdot.height = 10;
testdot.length = 15;
testline.insertDot(0,testdot);
a.addLine(testline);
a.addLine(testline);

Then I want to save the data about lengths and heights. And the structure, to know which dot belongs in which line.

I send that data to the webserver. I think these are the key lines to understand the used approach:

post = "name=" + name + "&tab=" + JSON.stringify(file);
req.open("POST", "saveFile.php", true);
req.send(post);

The saved file saves exactly what I wanted - the structure and data. But I don't know how to make it bee an object again. I am not insisting to use JSON.stringify() method. I would enjoy any approach that would let me save the content without repeatedly saving the methods.

Share Improve this question edited Apr 9, 2013 at 14:40 Džuris asked Apr 9, 2013 at 14:02 DžurisDžuris 2,2643 gold badges32 silver badges60 bronze badges 7
  • 2 what you need to save is a state of an object, methods are not part of the sate – Arun P Johny Commented Apr 9, 2013 at 14:04
  • how are your methods added? – Daniel A. White Commented Apr 9, 2013 at 14:04
  • @DanielA.White I add them in the object constructor with lines like these: this.print = printLines; function printLines() {...} – Džuris Commented Apr 9, 2013 at 14:06
  • @ArunPJohny Yes, that sounds like the right keywords, yet quick search didn't give me results how to do it. – Džuris Commented Apr 9, 2013 at 14:10
  • If you can share some more details about how the object is created and how it is structured we may be able to help you – Arun P Johny Commented Apr 9, 2013 at 14:13
 |  Show 2 more ments

2 Answers 2

Reset to default 1

If you are really hooked on the idea of saving the entire object for some reason then I suggest you use the toString() method of which will essentially return the code body of a function in the form of a string when called on a function.

var obj = { func: function() { alert('hello!'); };
for(var key in obj)
    if (typeof obj[key] === 'function')
       alert(obj[key].toString());

You would just have to add code to serialize and store this information in addition to the json data.

All that said, you really should be simply storing the state of your objects and reloading them into your application.

EDIT: Reconstructing the object client-side

Disclaimer: I am not a PHP guy so you will be left to finding an actually coding example but I'm confident there is one out there with the power of the almighty Google.

You simply need to use your serializing/deserializing class to serialize the data back into your object. So imagine the section of pseudo code is the php file for the particular page in question:

<?php
 <html>
      <head>
          <script type="text/javascript">
              var model = /* Use serializing class on your server-side object */;
              //Now you just need to build a function into your objects that is much like a constructor that can receive this model and rebuild the object

              function rebuildObject(yourObject, jsonModel) {
                  //assign first property
                  //assign second etc...
              }
           </script>
      </head>
      <body>
      </body>
</html>
?>

You are essentially templating the json data back to the page in a script tag so you can access it client-side. The javascript interpretter will automatically convert the json into an actual js object that your code can use so no issue there.

In the end I chose the straightforward way to recreate all the objects and copy the data. It turned out to be shorter and nicer than I had imagined before. In case it is useful for anyone else, here's how I did it:

data = JSON.parse(file);
a = new lines();

a.height = data.height;

for (var i=0; i<data.lines.length; i++)
{
    a.lines.push(new aLine());
    a.lines[i].height = data.lines[i].height;
    a.lines[i].length = data.lines[i].length;
    for (var j=0; j<data.lines[i].dots.length; j++)
    {
        a.lines[i].dots.push(new aDot());
        [... and so on ...]
    }
}

本文标签: jsonSaving Javascript objectStack Overflow