knockoutjs - debug with circular reference in view

2019-07-15 09:38发布

问题:

The view model has a circular reference, by design, making the use of <pre data-bind="text: ko.toJSON($data)"></pre> for debugging to throw:

Unable to parse bindings.
Message: TypeError: Converting circular structure to JSON;
Bindings value: text: ko.toJSON($data) 

Is there a way to work around this?

回答1:

It is ultimately the call to JSON.stringify inside of ko.toJSON that causes your error.

One way that you can control the output of your JSON is by supplying a toJSON function on your object as described here: http://www.knockmeout.net/2011/04/controlling-how-object-is-converted-to.html. That way you can remove the circular reference in the appropriate place.

There are a few other techniques that you could use for this as well.

  • You can pass a second argument to ko.toJSON. This is the replacer option to JSON.stringify as described here:

    https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/JSON/stringify.

    For example, you can pass an array of properties to include like:

    ko.toJSON(myobject, ["one", "two", "three"])
    
  • You can attach a property that you don't want to get turned into JSON as a "sub"-observable like:

    this.data = ko.observable();
    this.data.parent = parent;
    

In this case, data will get turned into JSON, but parent will just disappear, as it is a property on an observable that already gets unwrapped into its value.



回答2:

If you're open to add a reference to Dojo (may be just for debugging), then dojox.json.ref.toJson seems to be able to serialize JSON objects with circular references.

In this case, you can do:

<pre data-bind="text: dojox.json.ref.toJson($data)"></pre>

also there is this library worth checking that could probably provide a more lightweight solution than dojo: http://mixu.net/snapshot/



标签: knockout.js