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

can.Mustache: Array of objects passed as context to partials, breaks data helper and rendering. #288

Closed
bmomberger-reciprocity opened this Issue Feb 21, 2013 · 6 comments

Comments

Projects
None yet
3 participants
@bmomberger-reciprocity
Contributor

bmomberger-reciprocity commented Feb 21, 2013

http://jsfiddle.net/air_hadoken/gLMW3/3/ -- see part 5

What this is demonstrating is that, at the time a partial is called, the current context is an array of the context stack objects from the calling Mustache. This makes the data helper store the full array of context objects, instead of the object that would be considered the current context if the partial were not a partial (i.e. inlined).

This also makes {{#this}} iterate over all of the context stack objects (call_data2/nested_data2 templates).

A quick workaround for this, demonstrated with call_data3/nested_data3 is to use the property name of the desired context object within its parent.

@ghost ghost assigned andykant Feb 21, 2013

@andykant

This comment has been minimized.

Show comment
Hide comment
@andykant

andykant Mar 22, 2013

Contributor

I have a solution for this, but unfortunately it breaks something else (#227). Although, I think #227 is only working because of this bug.

Contributor

andykant commented Mar 22, 2013

I have a solution for this, but unfortunately it breaks something else (#227). Although, I think #227 is only working because of this bug.

@airhadoken

This comment has been minimized.

Show comment
Hide comment
@airhadoken

airhadoken Mar 22, 2013

Contributor

I keep coming back to the idea that the stack should become a subclass of can.Observe which implements push and pop. attr() as an accessor would return the first matching attribute by name. Where it would make sense, other function calls (e.g. bind) would pass through to the current head of the stack. Do you think this would be workable, @andykant ?

Contributor

airhadoken commented Mar 22, 2013

I keep coming back to the idea that the stack should become a subclass of can.Observe which implements push and pop. attr() as an accessor would return the first matching attribute by name. Where it would make sense, other function calls (e.g. bind) would pass through to the current head of the stack. Do you think this would be workable, @andykant ?

@andykant

This comment has been minimized.

Show comment
Hide comment
@andykant

andykant Mar 22, 2013

Contributor

It originally worked similar to what I think you're suggesting. We switched to the array-based stack because it was exponentially faster (~5-10x faster for a simple template with one live binding).

Contributor

andykant commented Mar 22, 2013

It originally worked similar to what I think you're suggesting. We switched to the array-based stack because it was exponentially faster (~5-10x faster for a simple template with one live binding).

@bmomberger-reciprocity

This comment has been minimized.

Show comment
Hide comment
@bmomberger-reciprocity

bmomberger-reciprocity Mar 22, 2013

Contributor

Good call, then.

It seems to me that the obvious answer is to set the "___st4ck" property on the array when you pass it to the partial. A quick fiddling confirmed the basics work; i.e. if I pass a mustache ref and an array to can.view and set ___st4ck=true on the array, it's treated as a context stack.

For the benefit of helpers, it might be a good idea to pass the full context stack as well, and add something like can.view.isStack and can.view.makeStack to let helper writers work with the system without exposing the magic tokens.

can.view.isStack = function(o) { return can.isArray(o) && !!o[STACK]; }

can.view.makeStack = function() { var a = can.makeArray(arguments); a[STACK] = true; return a }
Contributor

bmomberger-reciprocity commented Mar 22, 2013

Good call, then.

It seems to me that the obvious answer is to set the "___st4ck" property on the array when you pass it to the partial. A quick fiddling confirmed the basics work; i.e. if I pass a mustache ref and an array to can.view and set ___st4ck=true on the array, it's treated as a context stack.

For the benefit of helpers, it might be a good idea to pass the full context stack as well, and add something like can.view.isStack and can.view.makeStack to let helper writers work with the system without exposing the magic tokens.

can.view.isStack = function(o) { return can.isArray(o) && !!o[STACK]; }

can.view.makeStack = function() { var a = can.makeArray(arguments); a[STACK] = true; return a }

andykant added a commit that referenced this issue Mar 24, 2013

Merge pull request #334 from bitovi/data-helper-array-288
Fixed incorrect passing of context stacks with partials in Mustache #288

@andykant andykant closed this Mar 24, 2013

@airhadoken

This comment has been minimized.

Show comment
Hide comment
@airhadoken

airhadoken Mar 24, 2013

Contributor

👍

Contributor

airhadoken commented Mar 24, 2013

👍

@andykant

This comment has been minimized.

Show comment
Hide comment
@andykant

andykant Mar 24, 2013

Contributor

Context stacks will no longer get duplicated when updating the stack.

Helpers now get passed a copy of the stack in the options object (options.contexts) that can be passed to options.fn instead of this. This will allow the helper to still access references outside its original context (really only needed in weird cases with partials).

Contributor

andykant commented Mar 24, 2013

Context stacks will no longer get duplicated when updating the stack.

Helpers now get passed a copy of the stack in the options object (options.contexts) that can be passed to options.fn instead of this. This will allow the helper to still access references outside its original context (really only needed in weird cases with partials).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment