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 release] Ensure init is completed before didReceiveAttrs fires. #12260

Merged
merged 1 commit into from
Sep 8, 2015

Conversation

rwjblue
Copy link
Member

@rwjblue rwjblue commented Sep 1, 2015

Given the following example:

export default Ember.Component.extend({
  init() {
    this._super(...arguments);

    this.wasInitWithSomeThing = !!this.attrs.someThing;
  },

  didReceiveAttrs() {
    this._super(...arguments);

    if (this.wasInitWithSomeThing) {
      // do custom logic based on being `init` with `someThing`
    }
  }
});

Currently, the didReceiveAttrs (and also didInitAttrs) is firing from within the this._super() call in init (because we trigger these hooks in Ember.View's init). Which means that didReceiveAttrs can not have access to things set in init.

This change allows us to avoid that circumstance, and ensure that init is fully completed before didReceiveAttrs is fired and also ensures taht didReceiveAttrs/didInitAttrs is still fired from within the constructor before observation is started.

@@ -191,6 +191,10 @@ function makeCtor() {
this.init.apply(this, args);
}

if (this.__postInitInitialization) {
Copy link
Member

Choose a reason for hiding this comment

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

maybe just call it __postInit post initialization initialization is a bit redundant

Copy link
Member

Choose a reason for hiding this comment

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

actually, can we make this a symbol ? That way no user can use it, and it wont collide with anything else.

Copy link
Member

Choose a reason for hiding this comment

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

I'm slightly concerned that the property miss will not be as ideal as we would want, although I suspect today it is just in the noise.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, I will:

  • implement as a symbol (we can always tweak later)
  • add to base object to avoid property lookup (then remove if)

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated.

@stefanpenner
Copy link
Member

I'm unclear how this will work in ES6 class land. Unless keep init around, then something like:

constructor() {
  this.init
  this.__postInit()
}

…fires.

Given the following example:

```javascript
export default Ember.Component.extend({
  init() {
    this._super(...arguments);

    this.wasInitWithSomeThing = !!this.attrs.someThing;
  },

  didReceiveAttrs() {
    this._super(...arguments);

    if (this.wasInitWithSomeThing) {
      // do custom logic based on being `init` with `someThing`
    }
  }
});
```

Currently, the `didReceiveAttrs` (and also `didInitAttrs`) is firing
from within the `this._super()` call in `init` (because we trigger these
hooks in `Ember.View`'s `init`). Which means that `didReceiveAttrs` can
not have access to things set in `init`.

This change allows us to avoid that circumstance, and ensure that `init`
is fully completed before `didReceiveAttrs` is fired and also ensures
taht `didReceiveAttrs`/`didInitAttrs` is still fired from within the
`constructor` before observation is started.
@rwjblue
Copy link
Member Author

rwjblue commented Sep 1, 2015

I'm unclear how this will work in ES6 class land.

This was something that @mixonic also mentioned, and is something we should definitely decide on before merging this. I was under the impression that the idea that constructor and init are separate things would not change in ES6, if that is not the case (meaning we will make init the actual constructor) then we will also need to figure out a different path forward.

For additional context there are a few things that currently happen after init that will also need to be figured out. Things like finishChains and sending the on('init') event are both done after init today, and have the same issue as what this PR proposes.

@stefanpenner
Copy link
Member

@rwjblue ya i think we don't have a choice but to keep the two

@rwjblue
Copy link
Member Author

rwjblue commented Sep 2, 2015

Adding to the next core team meeting topics, but I'd like to get @mixonic and @wycats thoughts/review before so that we can discuss in detail.

@rwjblue
Copy link
Member Author

rwjblue commented Sep 5, 2015

We discussed this in the 2015-09-04 core team meeting. In general it seems that we had planned to have init be separate from constructor due to the other factors that I mentioned above. As such, this does not seem contentious.

I would still like to hear from @mixonic before landing.

@private
*/
[POST_INIT]: function() {
this._super(...arguments);
Copy link
Sponsor Member

Choose a reason for hiding this comment

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

meh, I would probably leave out the _super as it is a hook ;-)

mixonic added a commit that referenced this pull request Sep 8, 2015
[BUGFIX release] Ensure `init` is completed before `didReceiveAttrs` fires.
@mixonic mixonic merged commit 0ff1f46 into emberjs:master Sep 8, 2015
@mixonic mixonic deleted the init-before-didReceiveAttrs branch September 8, 2015 00:48
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.

3 participants