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

$onInit and friends #13763

Closed
wants to merge 20 commits into from
Closed

Conversation

petebacondarwin
Copy link
Member

No description provided.

* * a **string** containing the name of the directive to pass to the linking function
* * an **array** containing the names of directives to pass to the linking function. The argument passed to the
* linking function will be an array of controllers in the same order as the names in the `require` property
* * an **object** whose property values are the names of the directibes to pass to the linking function. The argument
Copy link
Member

Choose a reason for hiding this comment

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

directibes --> directives

@gkalpak
Copy link
Member

gkalpak commented Jan 13, 2016

With the exception of #13763 (comment) (and a couple of nitpicks), this L(pretty)GTM 👍

@@ -4244,6 +4244,22 @@ describe('$compile', function() {
if (!/chrome/i.test(navigator.userAgent)) return;
Copy link
Contributor

Choose a reason for hiding this comment

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

unrelated to this issue, but can we change this to if (!support.classes) return; ?

Copy link
Member Author

Choose a reason for hiding this comment

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

On it [sic]!

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually, it is not so easy @lgalfaso since the latest Safari (9.0.2) is even worse for toString on a a class instance.

Copy link
Contributor

Choose a reason for hiding this comment

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

it looks like there are at least 2 issues reported on JavascriptCore (Safari JS engine) regarding this
https://bugs.webkit.org/show_bug.cgi?id=149743
https://bugs.webkit.org/show_bug.cgi?id=144285

I think that some other strategy. Meanwhile, just keep the old code

…oller construction

This enables option three of angular#13510 (comment)
by allowing the creator of directive controllers using ES6 classes to have a hook
that is called when the bindings are definitely available.

Moreover this will help solve the problem of accessing `require`d controllers
from controller instances without resorting to wiring up in a `link` function.
See angular#5893
This provides an elegant alternative to the array form of the `require`
property but also helps to support binding of `require`d controllers
to directive controllers.
…ve controller

If directives are required through an object hash, rather than a string or array,
the required directives' controllers are bound to the current directive's controller
in much the same way as the properties are bound to using `bindToController`.

The binding is done after the controller has been constructed and all the bindings
are guaranteed to be complete by the time the controller's `$onInit` method
is called.

This change makes it much simpler to access require controllers without the
need for manually wiring them up in link functions. In particular this
enables support for `require` in directives defined using `mod.component()`
This provides an elegant alternative to the array form of the `require`
property but also helps to support binding of `require`d controllers
to directive controllers.
…ve controller

If directives are required through an object hash, rather than a string or array,
the required directives' controllers are bound to the current directive's controller
in much the same way as the properties are bound to using `bindToController`.

The binding is done after the controller has been constructed and all the bindings
are guaranteed to be complete by the time the controller's `$onInit` method
is called.

This change makes it much simpler to access require controllers without the
need for manually wiring them up in link functions. In particular this
enables support for `require` in directives defined using `mod.component()`
…oller construction

This enables option three of angular#13510 (comment)
by allowing the creator of directive controllers using ES6 classes to have a hook
that is called when the bindings are definitely available.

Moreover this will help solve the problem of accessing `require`d controllers
from controller instances without resorting to wiring up in a `link` function.
See angular#5893
…ve controller

If directives are required through an object hash, rather than a string or array,
the required directives' controllers are bound to the current directive's controller
in much the same way as the properties are bound to using `bindToController`.

The binding is done after the controller has been constructed and all the bindings
are guaranteed to be complete by the time the controller's `$onInit` method
is called.

This change makes it much simpler to access require controllers without the
need for manually wiring them up in link functions. In particular this
enables support for `require` in directives defined using `mod.component()`
*
* If the `require` property is an object and the directive provides a controller, then the required controllers are
* bound to the controller using the keys of the `require` property. See the {@link $compileProvider#component} helper
* for an example of how this can be used.
Copy link
Contributor

Choose a reason for hiding this comment

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

Should note that the controllers are only available once $onInit has been called, no?

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

@Narretz
Copy link
Contributor

Narretz commented Jan 14, 2016

Now that require can be an object, should we pass the ctrls as an object to the link function like described here: #8401? (Yes from me)

@Narretz
Copy link
Contributor

Narretz commented Jan 14, 2016

Don't forget that these issues are fixed by the PR:
#6040
#5893

@petebacondarwin
Copy link
Member Author

Now that require can be an object, should we pass the ctrls as an object to the link function like described here: #8401? (Yes from me)

@Narretz One of the commits in this PR does actually do that - but only when the require property is an object itself.

* is instantiated, the initial values of the isolate scope bindings will be available if the controller is not an ES6 class.
* allow a component to have its properties bound to the controller, rather than to scope.
*
* After the controller is instantiated, the initial values of the isolate scope bindings will bound to the controller
Copy link
Member

Choose a reason for hiding this comment

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

will bound --> will be? bound

Copy link
Member Author

Choose a reason for hiding this comment

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

done

@@ -4280,6 +4283,7 @@ describe('$compile', function() {
element = $compile('<div foo-dir dir-data="remoteData" ' +
'dir-str="Hello, {{whom}}!" ' +
'dir-fn="fn()"></div>')($rootScope);
expect(Controller.prototype.$onInit).toHaveBeenCalled();
element.data('$fooDirController').check();
Copy link
Member

Choose a reason for hiding this comment

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

Isn't this redundant now ?

Copy link
Member Author

Choose a reason for hiding this comment

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

yep! removed

@Narretz
Copy link
Contributor

Narretz commented Jan 15, 2016

I just noticed the component method doesn't accept the templateNamespace / multiElement property, is this intentional?

require: { container: '^parent', friend: 'sibling' },
bindToController: true,
controller: MeController,
controllerAs: '$ctrl'
Copy link
Member

Choose a reason for hiding this comment

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

Two controllerAs occurrences (where 1 would be sufficient).

@petebacondarwin
Copy link
Member Author

I just noticed the component method doesn't accept the templateNamespace / multiElement property, is this intentional?

@Narretz - I think we should try to keep the component API as simple as possible. These two are fairly uncommon, right? If people really need them they can complain and we can add them later.

@Narretz
Copy link
Contributor

Narretz commented Jan 15, 2016

@petebacondarwin Sounds good

@Narretz
Copy link
Contributor

Narretz commented Jan 15, 2016

There's a real travis failure btw:

Chrome 45.0.2454 (Linux 0.0.0) $compile isolated locals should eventually expose isolate scope variables on ES6 class controller with controllerAs when bindToController is true FAILED

Although the test wasn't introduced by this PR.

@petebacondarwin
Copy link
Member Author

@Narretz I have fixed that failing test.

@Narretz Narretz force-pushed the master branch 2 times, most recently from 70049ae to b77e14b Compare January 16, 2016 21:59
@ev45ive
Copy link

ev45ive commented Jan 17, 2016

This looks very nice and clean. Should be like this from beggining. Very nice work. Do you think $onInit with bound required controllers and component() syntax will get on board with 1.5 release? I'd love to use it in production - it would clean up a lot of messy directive code. :-)

Narretz pushed a commit to Narretz/angular.js that referenced this pull request Jan 19, 2016
petebacondarwin added a commit that referenced this pull request Jan 19, 2016
This provides an elegant alternative to the array form of the `require`
property but also helps to support binding of `require`d controllers
to directive controllers.

Closes #8401
Closes #13763
petebacondarwin added a commit that referenced this pull request Jan 19, 2016
…ve controller

If directives are required through an object hash, rather than a string or array,
the required directives' controllers are bound to the current directive's controller
in much the same way as the properties are bound to using `bindToController`.

This only happens if `bindToController` is truthy.

The binding is done after the controller has been constructed and all the bindings
are guaranteed to be complete by the time the controller's `$onInit` method
is called.

This change makes it much simpler to access require controllers without the
need for manually wiring them up in link functions. In particular this
enables support for `require` in directives defined using `mod.component()`

Closes #6040
Closes #5893
Closes #13763
@usernamealreadyis
Copy link

@Narretz I have fixed that failing test.

that's the point.... fixes all fail...

@petebacondarwin petebacondarwin deleted the onInit branch November 24, 2016 09:15
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants