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

Add ngModel support to UpgradeAdapter #8314

Closed
fenduru opened this issue Apr 28, 2016 · 12 comments
Closed

Add ngModel support to UpgradeAdapter #8314

fenduru opened this issue Apr 28, 2016 · 12 comments

Comments

@fenduru
Copy link

fenduru commented Apr 28, 2016

I have a number of reusable components that I would like to gradually migrate to Angular 2. Some of my components, however, use ngModel which as an attribute directive doesn't seem to have any support in UpgradeAdapter.

http://plnkr.co/edit/tD2wQROlcDUMWQOt0ra6

Since ngModel is a fundamental way of providing output values in Angular 1, would it be possible to add support to UpgradeAdapter to allow this interaction?

@jinaymehta25
Copy link

I am facing a similar issue. If not support what would be the correct way of handling this kind of situation?

@pselden
Copy link

pselden commented Jun 29, 2016

Updated plunker with latest rc -- http://plnkr.co/edit/TtZN8cjsRZG8eTpWHZUq?p=preview

I'll note that it looks like one of the main problems is that $postLink is not called at all!

@guojenman
Copy link

guojenman commented Aug 26, 2016

Just dug into the code and the short answer is that this is NOT currently possible.

it looks like UpgradeAdapter compiles only the childNodes of the component. Then it looks at the bindings and wires the input & output. This means that any ng1 attribute directives on the root node are ignored, including ngModel!!!!

UpgradeAdapter is nice but this limitation is a huge pitfall and I have to give it a grade of INCOMPLETE! :/

A workaround (which I do not recommend) it's to create a wrapper for any component that implements ngModel and use regular binding of ngModel and a variable. This workaround would be FUGLY and I do not recommend it.

@gkalpak
Copy link
Member

gkalpak commented Apr 18, 2017

Upgrading an AngularJS (1.x) component, essentially creates a thin Angular (2+) shell that can be used in Angular templates. When using something inside an Angular template, you must use Angular directives (e.g. Angular's ngModel vs AngularJS's ng-model, ngFor vs ng-repeat etc). This is expected behavior.

The same is true for downgraded Angular components: When used inside AngularJS templates, they should be used with AngularJS directives.

Note that this is not something specific to ngModel; it applies to all directives. Although most usecases should be covered, it is always possible to wrap a component that has very specific needs and upgrade the wrapper instead of the component itself.

Closing, since everything works as intended.

@gkalpak gkalpak closed this as completed Apr 18, 2017
@leff
Copy link

leff commented Apr 26, 2017

@gkalpak Your explanation has left me a little confused. Are you

A) trying to imply that you can upgrade AngularJS modules that require ng-model, but you need to somehow use ngModel in your html?
-or-
B) saying that it is impossible to upgrade AngularJS modules that require ng-model?

@gkalpak
Copy link
Member

gkalpak commented Apr 26, 2017

I am not sure what you mean by "AngularJS modules that require ng-model". How can a module require ng-model. You probably mean something else. In any case, showing an example of what you are trying to upgrade would help give a more specific answer 😉

@leff
Copy link

leff commented Apr 26, 2017

Example. No problem. Here is a simplified example of the component I'm trying to upgrade.

export let myParentComponent = {
  template: "<my-sub-component ng-model="vm.ngModel.$viewValue"></my-sub-component>",
  controller: MyController,
  controllerAs: "vm",
  require: {
    ngModel: "ngModel"
  },
};

Module:

angular.module("example", [])
.component("my-parent-component", myParentComponent);

Unfortunately, I didn't write the original. I'm not 100% sure why it was necessary to do it this way.

@gkalpak
Copy link
Member

gkalpak commented May 3, 2017

@leff, requiring something on the element itself is not "upgrade-able". This is because an upgraded component essentially becomes an Angular component (i.e. it is owned by Angular, not AngularJS). This also affects the directives that can appear on the element (so you can't have AngularJS directives on an upgraded component itself).

Anything inside the upgraded component's template is owned by AngularJS, so directives and filters etc work as expected there.

Although not related to your usecase, requiring from an ancestor (AngularJS) directive also works for upgraded components (it will look for the nearest AngularJS element that has the required directive):

<div id="1" class="plain-AngularJS-component" ng-model="foo">
  <div id="2" class="downgraded-Angular-component">
    <div id="3" class="upgraded-AngularJS-component">
       #3 can require ^ngModel and get it from #1
    </div>
  </div>
</div>

@fenduru
Copy link
Author

fenduru commented May 17, 2017

@gkalpak while your technical explanation is accurate, I'm not sure that it is actually helpful for those trying to upgrade their components that use ngModel from AngularJS to Angular.

It might be worth updating the documentation to indicate that while there is an ngModel in both AngularJS and Angular, there is no upgrade path between them provided by ngUpgrade and developers will need to rewrite these components.

@guojenman
Copy link

ngModel was the reason I abandoned the upgrade path and went with a full rewrite. It did take 2.5 months (50k lines for old app, 25k for new app). On the plus side, it's way easier in angular2 to write components which use ngModel, by far... and not having to test both angularJS AND angular2 every time also made testing way easier. just my 2 cents.

@tommck
Copy link

tommck commented Feb 27, 2019

So.... the answer to this is "rewrite your code"?

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 14, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants