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

AngularUI Router #9

Closed
freeman42x opened this issue Nov 4, 2013 · 11 comments
Closed

AngularUI Router #9

freeman42x opened this issue Nov 4, 2013 · 11 comments
Labels

Comments

@freeman42x
Copy link

Is it possible to use angularAMD with AngularUI Router? The routing in ui-router being done with $stateProvider and $urlRouterProvider (for default route).

@marcoslin
Copy link
Owner

If all you are looking for is to load controller using RequireJS syntax (i.e.: not on-demand loading), here is what you can do:
angular-ui/ui-router#479

On-demand loading should also be possible as ui-router also have a resolve property:
https://github.com/angular-ui/ui-router/wiki#resolve

You should be able to do something like:

$stateProvider.state('myState', {
    resolve: {
        "__load": ['$q', '$rootScope', function ($q, $rootScope) {
                var defer = $q.defer();
                require(['myStateController'], function () {
                    defer.resolve();
                    $rootScope.$apply();
                });
                return defer.promise;
        }]
    }
});

As I do not use ui-router, I am not sure if that actually works. If you setup a simple plunker with ui-router, I can try to wire angularAMD in. Here is a very simple angularAMD plunker as an example:
http://plnkr.co/edit/Pco6T6gVEEcp8IcWb4LX

@freeman42x
Copy link
Author

Thank you for your reply!

What I am hoping to accomplish is to load the AngularJS modules that contain all the JavaScript logic for the private part of the site (controllers, services, filters, directives, ...) when someone navigates to a child state under the "private" base/root state. The controllers, services, filters, directives, ... for the private/public part of the site will be split each in its own file and concatenated/minified into 1 file on build.

Is this achievable usingAMD? Am I going the right way about how to achieve this?

I created a plunker with ui-router as you requested: http://plnkr.co/edit/T7P9Dnd2dnJb2B9Czt13?p=preview

@marcoslin
Copy link
Owner

Ok, here is the updated plunker with on-demand loading of your private-modules.concat.js:
http://plnkr.co/edit/czs2G7qHmksiZAmILOcx?p=preview

Following is the summary of steps I've taken:

  1. All JS file were moved under a js directory
  2. Removed all script tag from index.html replacing with require.js call
  3. Created a js/main.js to define require.js dependencies
  4. Rewrote your js files as defined by require.js to allow on-demand loading
  5. Updated your route definition with resolve attribute to load needed js file via a helper function

Please note the following:

  1. ngAMD.bootstrap(); in js/app.js replaces ng-app="app" in your index.html
  2. As angular-ui-route.js is being loaded before ngAMD.bootstrap(), you do not need to use app.ngAMD.processQueue();. I need to update documentation to clarify this.
  3. As angular-ui-route.js is not a require.js module, need to define it's dependency to angular in the main.js file

Finally, I am working a 0.1.x that should make your requirement a little easier to define. The problem with the current 0.0.2 version is that it assume that you want to load all your application using require.js. However, in application like yours, the only part that you wanted to load on-demand is private-modules.concat.js. In short, just a warning that I will be introducing interface breaking changes in the '0.1.x' release.

@marcoslin
Copy link
Owner

Actually, ngAMD.route(...) works for ui-router as well. I updated plunker above replacing the helper function with ngAMD.route(...) calls.

@freeman42x
Copy link
Author

@marcoslin Thanks for your help and sorry for the late reply.

I had a look at the sample site and I'm thinking to load the private controllers, directives etc. in the way it is shown with the dataservices.js and dataservicesAMD.js.

But I don't know yet how to use grunt to change the requirejs configuration from development to production. In development the controllers, directives etc. should be loaded from separate files while in production they would be concatenated.

I will do more research and post here when I find out how.

@marcoslin
Copy link
Owner

Did the plunker I created not address your need? Can you give me some feedback on why it didn't and how you wish it could be improved?

As per issue #8, I am replacing the need to create a *AMD.js to a RequireJS plugin ngload in the version 0.1.x (code at devel branch). Basically, all you need to do eventually is:

define(['app', 'ngload!service/dataServices'], function (app) { ... })

Check out updated module_ctrl.js

As for using grunt to change RequireJS config, I have done that in the unit test for angularAMD, creating test for pre and post minification using mustache. It is not ideal but it works. If you do find something else, do keep me posted.

@freeman42x
Copy link
Author

The plunker you provided did address what I was asking for, only I was not expecting it to be done that way.
We decided to just go with separate public/private applications so there won't be any need for lazy loading.

About the gruntfile, possible I didn't look in the right place but I did not find a way to change the requirejs configuration. Could you provide a link to that file?

@dovidkopel
Copy link

AngularAMD works perfectly with ui-router for controllerUrl, but when used multiple views it is not functional. This functionality is documented here: https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views. I am thinking that you simply need to check for the "views" property, and interate through the object and check for the "controllerUrl" property and run the "route" function on that object.

I haven't tried that yet, wanted input if that is the proper way of handling that, or if maybe I am mistaken and there is support for this.

@marcoslin
Copy link
Owner

angularAMD rely on resolve property to provide the on demand loading of modules. From the documentation provided on ui-router's multiple view, it is not clear if resolve property is supported.

You can try to use angularAMD.route under view:

$stateProvider
  .state('report',{
    views: {
      'filters': { angularAMD.route({
        templateUrl: 'report-filters.html',
        controllerUrl: ''
      })},
      ...

@dovidkopel
Copy link

Of course, that makes perfect sense. I was just utilizing it on the entire state, but your suggestion is the obvious answer.

Thank you!

@riccardoroasio
Copy link

Hi,

i'm trying to use ui-router multiple views in this way:

.state('main', { url:'/app', // abstract: true, data: {requireLogin:true }, views:{ '': angularAMD.route({ templateUrl:function (){ var token=$cookies.get('token'); return '/getTemplate/'+token+'/main'; }, controller:'' }), 'main.content@main': angularAMD.route({ templateUrl:function (){ console.log("main.content template"); var token=$cookies.get('token'); return '/getTemplate/'+token+'/main.content'; }, controller:'main.content', controllerUrl:function (){ console.log("main.content controller");var token=$cookies.get('token'); return '/getController/'+token+'/main.content.js'; }//'main.content' }),

but it seems not to work... what i'm doing wrong?

Thanks,
Riccardo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants