-
Notifications
You must be signed in to change notification settings - Fork 27.4k
feat($injector): support instantiating classes. #12598
Conversation
Note: this change requires using |
tests are failing |
1ea5fec
to
df99769
Compare
@IgorMinar should be fixed (FF doesn't enable |
var clazz = eval('(class { constructor(a) { this.a = a; } aVal() { return this.a; } })'); | ||
var instance = injector.instantiate(clazz); | ||
expect(instance).toEqual({a: 'a-value'}); | ||
// Check if prototype is set up correctly.s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you are not checking the prototype + there is a typo at the end of the comment. I'd just remove this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, the call to aVal()
would fail if the prototype was incorrect. But point taken, dropped the comment.
PTAL. |
df99769
to
94ec404
Compare
#12614 is not fixed by this – |
It generally is, but this might not be too much of a problem for much longer. It's likely that the "new-only" restriction will be lifted, or otherwise a way of specializing a "call" behaviour/factory method for classes. In the mean time, you could add some other compat mechanism, like falling back on a static "init()" method if calling the constructor fails. There's no reason this couldn't be solved using conventions rather than language features |
@caitp: indeed, but what about doing that in another PR? |
Yeah, doesn't need to be this one, although that feature probably shouldn't be specific to controllers if we do that |
when can we expect this to work? |
94ec404
to
bb94223
Compare
@IgorMinar PTAL, I believe this is good to merge. It does not solve the issue for |
f27e77e
to
e0567ce
Compare
lgtm. @petebacondarwin should we wait with a merge until master is open for 1.5 beta features? |
@petebacondarwin, one more thing - this feature is not documented at all. where should the documentation live? |
for (i = 0, length = $inject.length; i < length; i++) { | ||
key = $inject[i]; | ||
for (var i = 0, length = $inject.length; i < length; i++) { | ||
var key = $inject[i]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why move the declarations of i
and key
here? Being var
declarations they will still be hoisted to the top of the function block.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also we seem to have lost the declaration of the length
variable here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
length
is delayed as part of the var declaration
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Declared, darned Swype
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@petebacondarwin I was moving the code around anyway, and I personally find it easier to declare things as close as possible to their respective use site, hoisting or not. Makes it easier to see what's used where and why, and also makes it easier to refactor code without forgetting to remove declarations.
I am not sure about this statement. Controllers can be instantiated very often. Every instance of a directive which defines a "directive controller" would need to instantiate a directive. Also imagine if you use |
I guess the documentation for this should be in the |
@petebacondarwin absent a good benchmark, this is all guesswork. However I would imagine the cost of this particular call being dwarfed by the cost of both |
ES6's `class Foo {}` constructors cannot be instantiated using `fn.apply`. This change extracts injection argument collection and then uses new (Function.bind.apply(ctor, args)) to instantiate the service instance.
e0567ce
to
06ecb4b
Compare
Friendly ping? |
@petebacondarwin is this too high risk for 1.5? several people at Google are asking for this change. |
@lgalfaso - what do you think? |
@IgorMinar it mostly moves code around, and it adds a little magic but it is reasonably documented. From my point of view, it looks safe for 1.5. If @petebacondarwin does not oppose, then I will merge it EOD Friday. |
Go for it @lgalfaso |
@petebacondarwin It looks like the commit does not affect later argument in |
sgtm On Thu, Dec 10, 2015 at 12:21 PM bisubus [email protected] wrote:
|
@bisubus - thanks for pointing that out. |
I have created the issue at #13510 |
ES6's
class Foo {}
constructors cannot be instantiated usingfn.apply
. This change extracts injection argument collection and thenuses
new (Function.bind.apply(ctor, args))
to instantiate the serviceinstance.
Fixes #12597.