Skip to content
This repository has been archived by the owner on Jan 12, 2020. It is now read-only.

Pass owner to constructor. #18

Closed
wants to merge 1 commit into from
Closed

Conversation

rwjblue
Copy link
Owner

@rwjblue rwjblue commented Dec 6, 2018

Ensure that services and other injected things work properly from the constructor.

Copy link
Contributor

@pzuraq pzuraq left a comment

Choose a reason for hiding this comment

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

👍 generally looks good. Only thing I would say is it seems weird for owner to come second, I imagine it'll probably be first in general with framework objects in the future, but I can also understand why you'd want to do this without making breaking changes.

tests/integration/components/sparkles-component-test.js Outdated Show resolved Hide resolved
@rwjblue
Copy link
Owner Author

rwjblue commented Dec 6, 2018

Only thing I would say is it seems weird for owner to come second, I imagine it'll probably be first in general with framework objects in the future,

Totally agree. My thought was to force it to be two args first, then swap them in a public API in a major version bump. Which should be easier...

Ensure that services and other injected things work properly from the
constructor.
@buschtoens
Copy link
Contributor

I just had an idea, which might be really stupid, but I would like your opinion on it. What if, instead of passing owner as an argument to the constructor, we use some global state?

Since super has to be called synchronously, we can be certain that nobody can interfere.

export const __OWNER_REFERENCE: { owner?: ApplicationInstance } = Object.create(null);

export default class SparklesComponentManager {
  // ..

  createComponent(Klass: typeof SparklesComponent, args: ComponentManagerArgs): CreateComponentResult {
    __OWNER_REFERENCE.owner = this.owner;
    let instance = new Klass(args.named);
	__OWNER_REFERENCE.owner = undefined;
    return instance as CreateComponentResult;
  }

  // ...
}
import { setComponentManager } from '@ember/component';
import { setOwner } from '@ember/application';
import { __OWNER_REFERENCE } from 'sparkles-component/component-managers/sparkles';

class SparklesComponent<T = object> {
  constructor(public args: T) {
    if (__OWNER_REFERENCE.owner) {
      setOwner(this, __OWNER_REFERENCE.owner);
    }
  }

  // ...
}

@rwjblue
Copy link
Owner Author

rwjblue commented Dec 13, 2018

Yep, definitely would work. I'm mostly trying to match the API of the upcoming glimmer component RFC, which currently has two args (owner and args). I'll cross link the RFC once its officially submitted (hopefully in the next day or so).

@buschtoens
Copy link
Contributor

@buschtoens
Copy link
Contributor

Is there anything holding this back? Can I help?

@pzuraq
Copy link
Contributor

pzuraq commented Feb 1, 2019

We decided to focus on GlimmerComponent implementation, since this would either not match the API, or be a breaking change


class SparklesComponent<T = object> {
constructor(public args: T) {}
constructor(public args: T, owner: any | undefined) {
Copy link

Choose a reason for hiding this comment

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

This is swapped now I believe

Copy link
Contributor

Choose a reason for hiding this comment

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

should be

Suggested change
constructor(public args: T, owner: any | undefined) {
constructor(public args: T, owner?: {}) {

to describe the following constraints:
(a) undefined need not be passed explicitly under any circumstances
(b) if an argument is passed, it cannot be null or undefined

Copy link
Owner Author

Choose a reason for hiding this comment

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

@mike-north - Seems good, should I use object or {}? (mostly just curious to the reasoning)

Copy link
Contributor

Choose a reason for hiding this comment

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

@rwjblue

let x: object = '';  // ❌
let x: {} = '';  // ✅

If you want to allow string, number Symbol and boolean, use {}
If you just want things that are assignable to JS Objects, use object

@rwjblue
Copy link
Owner Author

rwjblue commented Jan 11, 2020

See #33, closing in favor of using @glimmer/component directly.

@rwjblue rwjblue closed this Jan 11, 2020
@rwjblue rwjblue deleted the pass-owner-to-constructor branch January 11, 2020 19:03
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants