pbastowski / angular2-now

Angular 2 @Component syntax for Angular 1 apps
MIT License
145 stars 15 forks source link

Examples for @State with multiple named views? #6

Closed vacarsu closed 9 years ago

vacarsu commented 9 years ago

Normally this would look like

$stateProvider
      .state('root', {
        url: '/',
        redirectTo: '/main',
        views: {
          'navbar': { controller: 'NavbarCtrl as navbar', templateUrl: 'modules/navbar/navbar.html' },
          'root': { controller: 'RootCtrl as root', templateUrl: 'modules/root/root.html' }
        }
      });

But how would this looks when using the @ State decorator? I tried puting the views object inside and it didn't work.

pbastowski commented 9 years ago

@vacarsu Yes, using named views you would do that. However, you could also use components directly, without using named views, something like this:

First, define each of your sub components, "navbar" and "root"

@Component('navbar')
@View('modules/navbar/navbar.html')
class navBarComponent {}

@Component('root')
@View('modules/root/root.html')
class rootComponent {}

Then you'd use the above components in your "root" state's template and there would be no need for named views.

@State({ name: 'root', url: '/' })
@Component({ selector: 'my-app' })
@View('modules/app/app.html')
class myAppComponent { }

bootstrap(myAppComponent)

So, in your modules/app/app.html you would use <navbar> and <root> in place of <ui-view="navbar"> and <ui-view="root">, respectively.

vacarsu commented 9 years ago

Ahh I see they just become directives! Brilliant! thanks. I got it now.

Edit: One other thing, when using a top level module it seems you have to still import or use angular.extend(window, angular2now) on each child module? Is this true or am I doing something wrong?

pbastowski commented 9 years ago

Well, you shouldn't have to extend window with angular2now in each module. But, you do need to ensure that the module that does the extend runs before any other modules that depend on it.

So I would check in what order are your module files loaded.

vacarsu commented 9 years ago

Yes, I'll looks into, Meteors order of operations are quite complex, especially when moving a large mean stack app to meteor >.<

vacarsu commented 9 years ago

When I remove angular.extend(window, angular2now) from each module I get: Uncaught ReferenceError: Inject is not defined

Here is my top module:

angular.extend(window, angular2now)

// Tell angular2-now to set controllerAs to "vm", instead of the default componentName
// This is mostly because "vm" is shorter to type :)

angular.module('socially', [
  'angular-meteor',
  'ui.router',
  'angularUtils.directives.dirPagination',
  'uiGmapgoogle-maps',
  'ngMaterial',
  'ngAnimate',
  servicesModule.name,
  rootModule.name,
  navbarModule.name,
  homeModule.name
])
.config(appConfig);

// The bootstrap component's selector name must be the same as the module name.
@Component({ selector: 'socially' })
@View({ templateUrl: 'client/app/app.ng.html' })
@Inject(['$rootScope', '$state'])

class socially {
  constructor ($rootScope, $state) {
    /*$rootScope.$on("$stateChangeError",
      function (event, toState, toParams, fromState, fromParams, error) {
      // We can catch the error thrown when the $requireUser promise is rejected
      // and redirect the user back to the main page
      if (error === "AUTH_REQUIRED") {
        $state.go('parties');
      }
    })

    $rootScope.$watch('currentUser', function(nv, ov) {
      // user logout - redirect to parties-list
      if (!nv && ov) {
        $state.go('parties');
      }
    });*/

  }
}

bootstrap(socially);

(yes I am building off your angular-meteor example, while porting my app over.)

pbastowski commented 9 years ago

In my example code I don't actually extend window with angular2. See this:

https://github.com/pbastowski/meteor-angular-socially/blob/feature/ng2now/client/app/app.es6.js

However, that is probably not the source of the problem. Can you push your project to github, so that I can have a look at your setup?

Note: You could add

var { Inject, Service, Component, View, State, Filter, bootstrap } = angular2now;

to the top of each module, which will import the objects you need into those module's scope.

vacarsu commented 9 years ago

Here is the repo. https://github.com/vacarsu/angular2-now-meteor-example

pbastowski commented 9 years ago

Ok, I see the problem. You created some folders deeper than where app.es6.js is located. In Meteor files from the deepest folders get loaded first. Have a read of this, which should help: http://docs.meteor.com/#/basic/filestructure.

So, your home.es6.js, navbar.es6.js, etc files loaded before app.es6.js, which is why Inject, etc were not defined.

You could fix this in several different ways, such as moving your feature folders out of the modules folder and next to the app folder, which would put them on the same level as app and then app.es6.js would load first. Alternatively, you could do what I show in the image below. That is, create a lib folder in the app folder and put a single JS file in it with angular.extend(window, angular2now). Also, remove the same line from app.es6.js.

image

vacarsu commented 9 years ago

Well the reason why I have the folder stucture the way it is, is because all the dependant modules must load before the main app.js, putting the angular extend in a lib folder with app right now. That seems to have gotten things working as expected, thanks a bunch! I'll close this now.