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

[BUGFIX beta] Create a new hash parameter when creating a component cell #12712

Merged
merged 2 commits into from
Dec 21, 2015

Conversation

Serabe
Copy link
Member

@Serabe Serabe commented Dec 14, 2015

If we merge positional and hash parameters without duplicating the hash before,
then we get an error when rerendering.

Fixes test in #12711

@@ -74,12 +74,14 @@ export function isComponentCell(component) {
}

function createNestedClosureComponentCell(componentCell, params, hash) {
let newHash = assign(Object.create(null), hash);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, we do not use inheritance in hash objects (AFAIK). Do we really need to introduce that here?

Also, if we do, it should use new EmptyObject() instead (import EmptyObject from 'ember-metal/empty_object').

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll change it to new EmptyObject(). Thank you for the tip!

The thing is that processing positional params adds them to hash in place, therefore when component gets rerendered (or the component cell gets recomputed) the hash already has the value and the assertion fails. Other option would be to check that the param's name is not in the hash or, if it is, it is not exactly the same object.

Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I share @rwjblue hesitations about the prototype chain being the best way to resolve this.

@Serabe Serabe force-pushed the fix/positional-params-on-rerender branch from 3f6fc7a to d979491 Compare December 14, 2015 21:02

assert(`You cannot specify both a positional param (at position ${i}) and the hash argument \`${positionalParams[i]}\`.`,
!(positionalParams[i] in attrs));
isActiveStreamParam || !(positionalParams[i] in attrs));
Copy link
Sponsor Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this assertion against active doing? it would skip all bound positional params?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My fault. I checked out the file forgetting about the previous commit.

@mixonic
Copy link
Sponsor Member

mixonic commented Dec 14, 2015

The test here only asserts that {{component (component "-looked-up" name greeting="Hodi")}} works. There isn't a potential conflict of name in the test at all. This patch seems to attempt to ignore any conflicts between hash and positional params during closure creation. They don't seem to be solving the same problem?

@Serabe Serabe force-pushed the fix/positional-params-on-rerender branch from d979491 to d41021f Compare December 14, 2015 21:14
@Serabe
Copy link
Member Author

Serabe commented Dec 14, 2015

I'll try to explain this better. The problem is that processPositionalParams changes the input argument hash in place. The problem is that when creating a component closure, positional parameters get merged into the hash. This needs to be done at each level of closure nesting to avoid false assertions being raised.
If the positional parameter was bound, when its value is changed, the closure component cell gets recomputed. This causes the positional params to be merged into hash, which already was done in creation.

There are other options:

  1. Assertion is not raised if the value in params and the value in attributes is exactly the same. This can cause some assertion not being raised, like in the case {{my-component myName name=myName}} (the positional parameters is ['name']).
  2. Closure component cell is not dependant on anything. This might work now, because we only nest streams and not much more, but if some spread operator gets into handlebars, this can cause problems.
  3. Remove the assertion that was introduced when contextual components where introduced and choose a strategy of merging.

@rwjblue
Copy link
Member

rwjblue commented Dec 14, 2015

@Serabe - Thanks for the more detailed write up.

Would it be possible to allow disabling the assertion after the first render?

@Serabe
Copy link
Member Author

Serabe commented Dec 14, 2015

I can try. Is there any way inside the compute method of a stream to know if it is a recompute?

@Serabe Serabe force-pushed the fix/positional-params-on-rerender branch from d41021f to 7c52e37 Compare December 14, 2015 23:21
@Serabe Serabe changed the title [BUGFIX beta] Create a new hash parameter when creating a component cell [WIP] [BUGFIX beta] Create a new hash parameter when creating a component cell Dec 14, 2015
@Serabe
Copy link
Member Author

Serabe commented Dec 14, 2015

I did something, but I still don't fully like the solution. Another solution that might work is separating the processing from the assertions. Then, we can run the assertion at each cell component level and keep the positional parameters without processing them. Finally, the processing would be done normally, as any other component.

@Serabe
Copy link
Member Author

Serabe commented Dec 14, 2015

I added a WIP until a satisfactory solution is found.

@rwjblue
Copy link
Member

rwjblue commented Dec 15, 2015

The current state seems better to me than adding prototypal inheritance to the hash, but it is unfortunate to have to thread that extra argument through so much.

Another solution that might work is separating the processing from the assertions. Then, we can run the assertion at each cell component level and keep the positional parameters without processing them.

This sounds interesting to me. That way we could just process the assertions when the cell is created, right?

@Serabe
Copy link
Member Author

Serabe commented Dec 15, 2015

Yes. OTOH, for normal component we would go through the params twice (or we get duplicated code).

@Serabe
Copy link
Member Author

Serabe commented Dec 15, 2015

Furthermore, if we go through the separation, we need to create new arrays and hashes when nesting for the merge. Otherwise we get a bug when nesting the same closure in two different places.

@Serabe
Copy link
Member Author

Serabe commented Dec 16, 2015

I don't see many options right now except for to copy the attributes to a new object when creating the closure.

See this tweedle.

Long story sort: Ember processes positional params into the attributes, but does so in place. The components being rendered depend on this. I suggest doing this quick fix (copying the attributes inside the closure) and start looking at how to change the render process so processing positional params does not happen in place.

@mixonic
Copy link
Sponsor Member

mixonic commented Dec 18, 2015

@Serabe Yes, I agree. Building a new object is the right model- we should do that, then revisit for optimizations later on.

If we merge positional and hash parameters without duplicating the hash before,
then we get an error when rerendering.

Fixes test in emberjs#12711
@Serabe Serabe force-pushed the fix/positional-params-on-rerender branch from 7c52e37 to 4e7fe48 Compare December 20, 2015 13:26
@Serabe Serabe changed the title [WIP] [BUGFIX beta] Create a new hash parameter when creating a component cell [BUGFIX beta] Create a new hash parameter when creating a component cell Dec 20, 2015
@Serabe
Copy link
Member Author

Serabe commented Dec 20, 2015

Done. I need to tackle a different issue on parameters before starting to work on optimizations.

rwjblue added a commit that referenced this pull request Dec 21, 2015
[BUGFIX beta] Create a new hash parameter when creating a component cell
@rwjblue rwjblue merged commit c3a8dcd into emberjs:master Dec 21, 2015
@rwjblue
Copy link
Member

rwjblue commented Dec 21, 2015

Thanks @Serabe!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants