I am trying to create an undo process (reinitialize template) using a deep copy of a data-linked object. This may not be an ideal method, but I cannot use View Models, merge() and unmap() right now.
mainObject renders templateA (mainObject derived from AJAX request, Type: json)
mainObject = $.extend(true, mainObject, addObject); adds additional objects for editing purposes, renders templateB (addObject derived from AJAX request, Type: json)
I have been using the two above templates and objects without issues for quite some time.
Now...
I want to make a deep copy/clone of mainObject in the case the user cancels editing (two-way data-linked).
When I create mainObjectClone = JSON.parse(JSON.stringify(mainObject)) and re-render using the same template, templateB, I am getting errors related to context ~root.
It is my understanding that JSON.parse() returns the same type of object as AJAX request, Type: json.
Either the object is not returned or errors like: Uncaught TypeError: Cannot read property '0' of undefined. +((v=view.ctxPrm("root").myPhotos[j._sq(0)])!=null?v:"")
With debug turned on, all parts of template render fine except where ~root is used.
The strange thing is, ~root does not work where I have defined it in the template...but in further testing, if I add ~root to a 'different' top level object (one that doesn't need context), it works there strangely.
I have tried these and all break on ~root:
myObjectClone = $.extend(true, {}, mainObject)- Lodash deep copy
- Also reversing object order
mainObject, addObjecttomainObject = $.extend(true, addObject, mainObject)breaks~rootaccess too (first object gets extended).
I have tried but failed to reproduce the issue in jsfiddle...although with limited data/template.
Console log shows all objects as correctly formed.
How does ~root get created/initialized...on some or all objects?
What code conflicts might alter the ~root context?
Any tips or pointers would be appreciated.
UPDATE
Although I have commented out all helpers, etc, to bare-bones template + data (with debug on)...the ~root issue still remained. This 'finally' led me to believe this had nothing to do with the template or data.
So here is my scenario:
- TemplateA is rendered using link() with DataA (no issues)
- TemplateB is rendered using link() with deep copy/clone object (DataA + DataB) (~root issue)
- Templates A & B share common two-way data-linked items, although from different data sources.
If I change TemplateA render method to render() (instead of link()); and then render TemplateB, ~root context works.
Another scenario: instead of rendering TemplateB with deep copy/clone object (DataA + DataB)...I combined the data on the server and rendered against that. This also produced the ~root context issue.
I then thought maybe there was an issue when link() is called from multiple templates that their objects with same name would conflict. So I isolated one of the common objects, renamed it and rendered a test template with name changes....~root issue remained.
That's all I know for now ;-)
Answering my own question here...
There was no problem with JsViews here...the issue with ~root was of my own creation ;-)
The problem was cause by injecting link() templateB into link() templateA...thus creating a conflict with ~root.
My data sources and templates used to be combined...I split them for testing and wasn't thinking clearly.
Essentially I was doing this:
The fix is pretty easy, something like this:
This solves the ~root issue and also deep copy object methods now work.