-
Notifications
You must be signed in to change notification settings - Fork 25.1k
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
feat(upgrade): Support ng-model in downgraded components #10578
Conversation
56e8d2d
to
dad6b86
Compare
Update: ran gulp lint |
holding this PR until after RC6 settles |
dad6b86
to
ea9f4f3
Compare
Resolved conflicts. |
It might be just me, but I feel this crosses the "too much magic under the hood" boundary. I do understand that I haven't thought this through, rather thinking out loud:
|
I have a similar feeling, although I am not sure we could manage it through an Angular 1 directive since it would not have access to or knowledge of the Angular 2 downgraded component. In any case I think it would be important to make this a bit more general, perhaps some way of exposing controllers to downgraded components? If that is not already possible? |
A generalizable way of exposing controllers would be nice, but you'd then need ng1 directives that are able to work with ng2 controllers. That's probably an ok requirement for user-generated controllers, but ng-model is so fundamental to Angular that excluding it leaves out a huge percentage of otherwise viable components. It would be good to look at a solution going the other way as well - allowing upgraded ng1 components to interoperate with ng2's NgModel as well. |
Actually the more I look at this PR the more I think it is reasonable, given the status of ngModel in the framework. |
I'll have time to get this updated next week - would you like me to take a look at this feature for upgraded components as well? |
@kseamon - yes that would be great. Also we need it to work for |
9e62b98
to
2d0fb3f
Compare
Synced up with master. |
Looks like I need to more or less copy these changes into the aot subdirectory as well? |
That sounds about right. @gkalpakas is working on a PR to unify the two
libraries on some level. But in the meantime there is duplication.
…On Thu, 19 Jan 2017 at 16:06 Karl Seamon ***@***.***> wrote:
Looks like I need to more or less copy these changes into the aot
subdirectory as well?
—
You are receiving this because you were assigned.
Reply to this email directly, view it on GitHub
<#10578 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAA9J2w9ta3J4DVlznUgb6vBT-JiEhpCks5rT4n0gaJpZM4Jfgnw>
.
|
2d0fb3f
to
cbf595b
Compare
Added in the aot stuff. Unit tests are passing for me but there seems to have been a timeout or tool failure in travis for ios 7. Any way to rerun the tests to see if it is a fluke? |
I can rerun them... |
One other note: as I'm diving into this again to try to figure out making this work the other way (for upgrading ng1 directives) I noticed that both ng1 and ng2 have hooks for "touched" (which is really blurred - not a touch event). Probably worth adding it, but not going to bother for this PR. |
Seems to pass now. I'll review tomorrow. |
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.
Nothing but minor refactoring that could be done here or in a subsequent PR.
@@ -47,6 +47,13 @@ export class DowngradeComponentAdapter { | |||
childInjector, [[this.contentInsertionPoint]], this.element[0]); | |||
this.changeDetector = this.componentRef.changeDetectorRef; | |||
this.component = this.componentRef.instance; | |||
|
|||
if (this.ngModel && typeof this.component.writeValue === 'function' && | |||
typeof this.component.registerOnChange === 'function') { |
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.
I kind of feel like I would like this test to be factored out so that it is clear what we are checking for. E.g. implementsControlValueAccessor(this.component)
or similar.
this.ngModel.$render = () => { this.component.writeValue(this.ngModel.$viewValue); }; | ||
|
||
this.component.registerOnChange(this.ngModel.$setViewValue.bind(this.ngModel)); | ||
} |
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.
Although I said we would need copy duplicate a lot of the code we could actually factor out this whole section of code into a function that is shared between dynamic and static versions. Perhaps put it in https://github.com/angular/angular/blob/master/modules/%40angular/upgrade/src/util.ts?
@@ -138,6 +138,9 @@ export class UpgradeAdapter { | |||
* 2. Even thought the component is instantiated in Angular 1, it will be using Angular 2+ | |||
* syntax. This has to be done, this way because we must follow Angular 2+ components do not | |||
* declare how the attributes should be interpreted. | |||
* 3. ng-model is controlled by AngularJS v1 and communicates with the downgraded Ng2 component | |||
* by way of the ControlValueAccessor interface from @angular/forms. Only components that | |||
* implement this interface are elligible. |
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.
eligible
this._onChangeCallback(newValue); | ||
} | ||
} | ||
let ng2Instance: Ng2; |
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.
I think this declaration should go above the class, since let
is not hoisted.
@kseamon thanks for this. Let me know if you want to make the changes I suggested or just merge this as-is. |
These changes are pretty straightforward so I'll take care of them now. That will also give us some time to discuss where I'm at with upgraded components - I'll start that conversation in slack now. |
cbf595b
to
1e46747
Compare
Suggested changes have been applied. |
@kseamon thank you. +100500 for you karma 🎉 🎉 🙌 This feature solves problem of syncing Angular component state with AngularJS NgFormController. Does angular have some mechanism for setting validity of NgFormController AngularJS form accordingly to validity of component itself? I can't find anything at the moment. If it is not, I am sure is not hard to add this. Something like:
What do you think about this? |
I created #23085. |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
What kind of change does this PR introduce? (check one with "x")
What is the current behavior? (You can also link to an open issue here)
No form of ngModel is supported. Components that require it, such as MdInput are not usable via ngDowngrade.
What is the new behavior?
The AngularJS ng-model can now bind to Components that implement the ControlValueAccessor interface.
Does this PR introduce a breaking change? (check one with "x")
If this PR contains a breaking change, please describe the impact and migration path for existing applications: ...
Other information: