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

Live Binding Broken with Models with Nested Sub-models #457

Closed
thecountofzero opened this issue Aug 9, 2013 · 10 comments
Closed

Live Binding Broken with Models with Nested Sub-models #457

thecountofzero opened this issue Aug 9, 2013 · 10 comments
Assignees
Milestone

Comments

@thecountofzero
Copy link
Contributor

This is occurs with models that have nested models as attributes.

For example, a player model has an attribute named team which is a model. The team model has an attribute named players which is a list of player models which contains the original player model. So A contains B and B contains A.

This is all setup by using the attribute plugin.

I issue a findOne for the player model and pass the player to an EJS for rendering (with live binding).

The problem is that if later I do another findOne for the same model and any of its live binded value have changed, they are not being updated in the UI.

After a few hours of WTFs and digging, here's what I discovered.

When the initial findOne is executed and Can is parsing the incoming JSON into the appropriate models, here's what seems to happen.

It creates a new model for the player model and then begins parsing all of it's attributes. When it gets to the "team" attribute it knows from the attributes property of the player model that "team" is a team model, so it creates a new team model which it then begins to process. When it gets to the "players" attribute it says "ok these are player models" and creates new player models. It even creates another new player model for the player data that matches the original player model that all of this data is a part of. They have different _cid values.

When the processing/parsing is complete, findOne is resolved with the outermost instance of the player model. That is the instance that is passed into the EJS. However that is not the instance that is in the model store. The instance in the model store is the one that is in the "player" attribute of the team model. Therefore live binding is broken.

Please see the attached fiddle. When you click the "Fetch Game" button, I am changing the fixture to point to a different data set. This should result in the value printed for league to be changed from "League of Kings" to "Hoboken Heroes", but it doesn't.

If, however, you comment out line #14 which sets up the association between a team and its games attribute, then live binding works.

http://jsfiddle.net/thecountofzero/HMYCX/

@justinbmeyer
Copy link
Contributor

This isn't a problem with live binding it seems, more the model store. If you change the appropriate instance, does the page update?

It's probably pretty easy to submit a breaking test for this. Re-create the model association and do new Player(data) with the appropriate data.

Then go through the instances it created and verify that ones sharing the same id share the same cid.

@thecountofzero
Copy link
Contributor Author

You are correct. It is not a problem with live binding as the page does update if you update the appropriate instance.

I will create the breaking test for this tomorrow.

Thanks for the reply.

@thecountofzero
Copy link
Contributor Author

Was just about to submit a failing test, but it looks like someone beat me to it.

@thecountofzero
Copy link
Contributor Author

Test I see in model_test.js is for Issue #357

Are these issues related?

thecountofzero added a commit to thecountofzero/canjs that referenced this issue Aug 16, 2013
@thecountofzero
Copy link
Contributor Author

@justinbmeyer, hey dude, any time to look at this one?

@thecountofzero
Copy link
Contributor Author

Somehow we need to keep track of models of the same model type and ID while they are being processed in "model"

@ghost ghost assigned justinbmeyer Sep 22, 2013
@justinbmeyer
Copy link
Contributor

I'll take a look at it now ...

@justinbmeyer
Copy link
Contributor

Thanks for the test, but don't create globals in them :-).

Game = can.Model({

@thecountofzero
Copy link
Contributor Author

Whoops. Forgot "var". Bad me.

@justinbmeyer
Copy link
Contributor

I fixed this by adding things to the store before the attributes are processed.

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

No branches or pull requests

2 participants