ngUpgraders / ng-forward

The default solution for those that want to write Angular 2.x style code in Angular 1.x
411 stars 36 forks source link

Create example of using ng-forward to upgrade existing ng1 project #30

Closed timkindberg closed 8 years ago

david-gang commented 8 years ago

My view is that people following the John Papa angular style guide should be able to migrate the project as easy as possible. The main obstacle is the lack of out the box modules here. In the style guide every object is put in a distinct file in a closure (revealing pattern). Every object is registered with an angular module.

How do we maintain the structure of the project which is great for clarity and support the modularity of the project, without putting all objects of a module in the same file.

There would be two options i think about:

aciccarello commented 8 years ago

I think that the modularity in Angular 2 is managed by ES2015 module syntax. Is it required to use ES2015 modules to use ng-forward? Our team is already using them but for other projects it would be a significant change.

MikeRyanDev commented 8 years ago

There are internal tools in ng-forward that let you take an ng-forward component and turn it into a regular Angular 1 module. We need to do some work to make this function easier to get a hold off, however once that is complete you will absolutely be able to follow the modules pattern in John Papa's styleguide:

import {bundle, Component} from 'ng-forward';

@Component({
  selector: 'my-component'
})
class MyComponent{ }

// This line creates an angular.module with a name of 'app.my-component'
bundle('app.my-component', MyComponent);

ES2015 is currently a requirement to use ng-forward but this is only because the project is in its early days. We would really like to support ES5 users in much the same way Angular 2 does. This may end up looking something like this:

ngForward
.Component({
  selector: 'my-component',
  inputs: [],
  outputs: []
})
.class({
  constructor: function(){

  }
})
.bundle('app.my-component')
david-gang commented 8 years ago

Thanks.

I just want to be sure that not just the angular.module('x',[]) will be possible. Also that the angular.module('x') will be available.

This is important because according to the style guide the module definition spans many files, so we have many places where we call angular.module and there isn't one place where we bundle all controllers/services/directives in one module. Rather the module is created in a .module file and the angular objects are added incrementally into the module in the other files (.controller, .directive, .service).

So that the following setup should also be possible:

MyComponent.js

import {bundle, Component} from 'ng-forward';

@Component({
  selector: 'my-component'
})
class MyComponent{ }

// This line creates an angular.module with a name of 'app.my-component'
bundle('app.my-component', MyComponent);

MyComponent1.js

import {bundle, Component} from 'ng-forward';

@Component({
  selector: 'my-component1'
})
class MyComponent1{ }

// This adds to the module 'app.my-component' the MyComponent1
bundle('app.my-component', MyComponent1);

Is this correct?

MikeRyanDev commented 8 years ago

I think so, except we will need to differentiate between setting/getting the module. Maybe something like this would work and feel consistent?

// New bundle:
bundle('app.my-component', MyComponent1, [ 'ui.router' ]);

// Reference bundle:
bundle('app.my-component', MyComponent1);
MikeRyanDev commented 8 years ago

The issue that is going to arise is that you specify providers on each component. Take this example:

@Injectable()
class ServiceA{ }

@Injectable()
class ServiceB{ }

@Component({
  selector: 'component-a',
  providers: [ ServiceA ]
})
class ComponentA{ }

bundle('app.my-component', ComponentA);

@Component({
  selector: 'component-b',
  providers: [ ServiceB ]
})
class ComponentB{ }

bundle('app.my-component', ComponentB);

At the first bundle call, we have no knowledge that ServiceB should be included in the angular.module. It may be the case that a limitation of ng-forward is that you will only be able to use bundle to create new angular modules, not reference existing ones.

timkindberg commented 8 years ago

@david-gang I'm feel like the john papa style guide will change for Angular 2 (and thus ng-forward). It no longer makes sense to declare an angular module somewhere and then add onto it in separate files.

I took some time to create some example gists that illustrate an imaginary migration. Please walk through them and see if they help at all.

Migration Example:

david-gang commented 8 years ago

Hi @timkindberg. I will take a look at it and get back to you till Sunday. Thanks David

timkindberg commented 8 years ago

I added my example to the README, which closes this.

david-gang commented 8 years ago

I saw that this issue was closed so i put my remarks in the gist itself. Thanks

timkindberg commented 8 years ago

We can keep talking about it here.

Do this look more like what you are expecting: Part 1 Alternative

timkindberg commented 8 years ago

And here would be the Part 2 Alternative

david-gang commented 8 years ago

This looks very nice. I will try actually to convert my application with this recipe and will tell you if it goes well.

timkindberg commented 8 years ago

Ok we will keep this open for now. Please check back in with your results and we'll close this or go from there.

timkindberg commented 8 years ago

@david-gang do you think my examples suffice for now and we can close this issue?

david-gang commented 8 years ago

Yes 👍 This helped a lot