Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unusual approach to nested $.render() calls leads to a bug when useViews advanced setting is false #333

Closed
earshinov opened this issue Nov 16, 2017 · 4 comments

Comments

@earshinov
Copy link

We are having trouble upgrading from v1.0.0-beta to a more recent version.

Please see JsFiddle: https://jsfiddle.net/psqu0ttw/3/
Instead of rendering "1 2" it produces an error (visible in Chrome DevTools).

We have an hierarchy of views, each of which is capable of rendering itself via a call to $.render.

In the example from the fiddle, an outer view renders two inner views in its template. Rendering the first inner view results in a nested call to $.render. Apparently something goes wrong, because rendering the second view fails with an error. In order for the error to occur, the if in the template must be present and have a condition. The condition itself can be anything, though.

The example works correctly using v1.0.0-beta and seems to fail when any recent version is used (tried 0.9.84 and 0.9.89).

@earshinov
Copy link
Author

Let me put the code here for convenience:

<script id="tpl-outer" type="text/x-jquery-tmpl">
  {{:a.getHtml()}}
  {{if true}}{{:b}}{{/if}}
</script>

<script id="tpl-inner" type="text/x-jquery-tmpl">
  1
</script>
function renderTemplate(templateId, data) {
  if (!$.render[templateId])
    $.templates(templateId, "#" + templateId);
  return $.render[templateId](data);
}

class InnerView {
  getHtml() { return renderTemplate("tpl-inner", this); }
}

class OuterView {
  constructor(a, b) { this.a = a; this.b = b; }
  getHtml() { return renderTemplate("tpl-outer", this); }
}

var a = new InnerView();
var b = 2;
var outer = new OuterView(a, b);
alert(outer.getHtml());

@BorisMoore
Copy link
Owner

Ah - yes - there is special perf optimization code that was not used in the v1.0.0-beta - and you have revealed a rather obscure bug in that code, due to your unusual mix of declarative and programmatic rendering. Thanks for letting me know...

I will fix the bug in the next update, but there is a workaround you can use immediately which is to set:

$.views.settings.advanced({useViews: true});

See http://www.jsviews.com/#settings/advanced

With that setting, you should be able to move to any recent version...
v1.0.0-beta

@earshinov
Copy link
Author

Thank you for the clarification. I think we will wait for the next update.

@BorisMoore BorisMoore changed the title Nested $.render call messes up rendering context resulting in a crash Unusual approach to nested $.render() calls leads to a bug when useViews advanced setting is false Nov 20, 2017
@BorisMoore BorisMoore added the Bug label Nov 20, 2017
BorisMoore added a commit to BorisMoore/jsviews.com that referenced this issue Nov 28, 2017
Minor bug fixes:

- Tags and converters with 'depends' as a function: the function now
  receives the tag as 'this' pointer and the contextual data object as
  parameter

- Fix for syntax error bug for debugMode(true) with {{else}} blocks
  https://stackoverflow.com/questions/47065521/migrating-jsrender-to-jsviews-else-issue
  BorisMoore/jsviews#395

- Fix for bug in advanced nested $.render() call scenarios (when
  useViews advanced setting is false):
  BorisMoore/jsrender#333

- linkedCtxParam bugs:
  - If linkedCtxParam="foo", and onUpdate is not false, two-way binding
    on ~foo continues to work correctly after an update
  - If linkedCtxParam="foo", 2 way binding now works correctly
    for properties of ~foo (~foo.bar...)

- Fix for validation bug for 'preventInvalidData'. Now uses
  onBeforeUpdateValue rather than onBeforeChange

Feature improvements and changes for custom tags:

- Very minor breaking changes:
  - The (undocumented) onBeforeBind event has been removed
  - Signature change for tag.cvtArgs(): does not accept a converter
    parameter

- 'lateRender' is now available as a tag option (overridden by inline
  lateRender=false)

- 'trigger' is now available as a tag option (overridden by inline
 trigger=...)

- 'linkedElement' and 'linkedCtxParam' can now be set in init()

- If a tag has no args, and argDefault is not set to false, then the
  tagCtx.args[] will be [#data] (where #data is the current data
  context). Note that the render() method will receive the current data
  as parameter. (See https://www.jsviews.com/#tagsapi@argdefault)

Unit tests:

- Several additional unit tests

Documentation:

- JsViews custom tag controls topic has been augmented. (More content to
  be added in next updates) See: http://www.jsviews.com/#jsvtagcontrols
BorisMoore added a commit to BorisMoore/jsviews.com that referenced this issue Nov 29, 2017
Minor bug fixes:

- Tags and converters with 'depends' as a function: the function now
  receives the tag as 'this' pointer and the contextual data object as
  parameter

- Fix for syntax error bug for debugMode(true) with {{else}} blocks
  https://stackoverflow.com/questions/47065521/migrating-jsrender-to-jsviews-else-issue
  BorisMoore/jsviews#395

- Fix for bug in advanced nested $.render() call scenarios (when
  useViews advanced setting is false):
  BorisMoore/jsrender#333

- linkedCtxParam bugs:
  - If linkedCtxParam="foo", and onUpdate is not false, two-way binding
    on ~foo continues to work correctly after an update
  - If linkedCtxParam="foo", 2 way binding now works correctly
    for properties of ~foo (~foo.bar...)

- Fix for validation bug for 'preventInvalidData'. Now uses
  onBeforeUpdateValue rather than onBeforeChange

Feature improvements and changes for custom tags:

- Very minor breaking changes:
  - The (undocumented) onBeforeBind event has been removed
  - Signature change for tag.cvtArgs(): does not accept a converter
    parameter

- 'lateRender' is now available as a tag option (overridden by inline
  lateRender=false)

- 'trigger' is now available as a tag option (overridden by inline
 trigger=...)

- 'linkedElement' and 'linkedCtxParam' can now be set in init()

- If a tag has no args, and argDefault is not set to false, then the
  tagCtx.args[] will be [#data] (where #data is the current data
  context). Note that the render() method will receive the current data
  as parameter. (See https://www.jsviews.com/#tagsapi@argdefault)

Unit tests:

- Several additional unit tests

Documentation:

- JsViews custom tag controls topic has been augmented. (More content to
  be added in next updates) See: http://www.jsviews.com/#jsvtagcontrols
BorisMoore added a commit that referenced this issue Nov 29, 2017
Sync with changes in v0.9.90 for JsViews

Minor bug fixes, including:

- Fix for syntax error bug for debugMode(true) with {{else}} blocks
  BorisMoore/jsviews#395

- Fix for bug in advanced nested $.render() call scenarios (when
  useViews advanced setting is false):
  #333

Minor change for custom tags:

- If a tag has no args, and argDefault is not set to false, then the
  tagCtx.args[] will be [#data] (where #data is the current data
  context). Note that the render() method will receive the current data
  as parameter. (See https://www.jsviews.com/#tagsapi@argdefault)

Unit tests:

- Some additional unit tests
BorisMoore added a commit to BorisMoore/jsviews.com that referenced this issue Nov 29, 2017
Minor bug fixes:

- Tags and converters with 'depends' as a function: the function now
  receives the tag as 'this' pointer and the contextual data object as
  parameter

- Fix for syntax error bug for debugMode(true) with {{else}} blocks
  https://stackoverflow.com/questions/47065521/migrating-jsrender-to-jsviews-else-issue
  BorisMoore/jsviews#395

- Fix for bug in advanced nested $.render() call scenarios (when
  useViews advanced setting is false):
  BorisMoore/jsrender#333

- linkedCtxParam bugs:
  - If linkedCtxParam="foo", and onUpdate is not false, two-way binding
    on ~foo continues to work correctly after an update
  - If linkedCtxParam="foo", 2 way binding now works correctly
    for properties of ~foo (~foo.bar...)

- Fix for validation bug for 'preventInvalidData'. Now uses
  onBeforeUpdateValue rather than onBeforeChange

Feature improvements and changes for custom tags:

- Very minor breaking changes:
  - The (undocumented) onBeforeBind event has been removed
  - Signature change for tag.cvtArgs(): does not accept a converter
    parameter

- 'lateRender' is now available as a tag option (overridden by inline
  lateRender=false)

- 'trigger' is now available as a tag option (overridden by inline
 trigger=...)

- 'linkedElement' and 'linkedCtxParam' can now be set in init()

- If a tag has no args, and argDefault is not set to false, then the
  tagCtx.args[] will be [#data] (where #data is the current data
  context). Note that the render() method will receive the current data
  as parameter. (See https://www.jsviews.com/#tagsapi@argdefault)

Unit tests:

- Several additional unit tests

Documentation:

- JsViews custom tag controls topic has been augmented. (More content to
  be added in next updates) See: http://www.jsviews.com/#jsvtagcontrols
BorisMoore added a commit to BorisMoore/jsviews that referenced this issue Nov 29, 2017
Minor bug fixes:

- Tags and converters with 'depends' as a function: the function now
  receives the tag as 'this' pointer and the contextual data object as
  parameter

- Fix for syntax error bug for debugMode(true) with {{else}} blocks
  https://stackoverflow.com/questions/47065521/migrating-jsrender-to-jsviews-else-issue
  #395

- Fix for bug in advanced nested $.render() call scenarios (when
  useViews advanced setting is false):
  BorisMoore/jsrender#333

- linkedCtxParam bugs:
  - If linkedCtxParam="foo", and onUpdate is not false, two-way binding
    on ~foo continues to work correctly after an update
  - If linkedCtxParam="foo", 2 way binding now works correctly
    for properties of ~foo (~foo.bar...)

- Fix for validation bug for 'preventInvalidData'. Now uses
  onBeforeUpdateValue rather than onBeforeChange

Feature improvements and changes for custom tags:

- Very minor breaking changes:
  - The (undocumented) onBeforeBind event has been removed
  - Signature change for tag.cvtArgs(): does not accept a converter
    parameter

- 'lateRender' is now available as a tag option (overridden by inline
  lateRender=false)

- 'trigger' is now available as a tag option (overridden by inline
 trigger=...)

- 'linkedElement' and 'linkedCtxParam' can now be set in init()

- Calling tag.updateValue() now updates both external bindings and internal
  content dependencies (which it updates by calling tag.setValue()...)

- If a tag has no args, and argDefault is not set to false, then the
  tagCtx.args[] will be [#data] (where #data is the current data
   context). Note that the render() method will receive the current data
   as parameter. (See https://www.jsviews.com/#tagsapi@argdefault)

Unit tests:

- Several additional unit tests

Documentation:

- JsViews custom tag controls topic has been augmented. (More content to
  be added in next updates) See: http://www.jsviews.com/#jsvtagcontrols
@BorisMoore
Copy link
Owner

This has been fixed in release v0.9.90.

If you still see any issues, let me know.

It is probably a good idea in your scenario to set useViews to true ($.views.settings.advanced({useViews: true}); - though with the fix it should still work correctly even if you don't.

pull bot pushed a commit to KiarashS/jsrender that referenced this issue Apr 2, 2020
Sync with changes in v0.9.90 for JsViews

Minor bug fixes, including:

- Fix for syntax error bug for debugMode(true) with {{else}} blocks
  BorisMoore/jsviews#395

- Fix for bug in advanced nested $.render() call scenarios (when
  useViews advanced setting is false):
  BorisMoore#333

Minor change for custom tags:

- If a tag has no args, and argDefault is not set to false, then the
  tagCtx.args[] will be [#data] (where #data is the current data
  context). Note that the render() method will receive the current data
  as parameter. (See https://www.jsviews.com/#tagsapi@argdefault)

Unit tests:

- Some additional unit tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants