marcoslin / angularAMD

Facilitate use of RequireJS in AngularJS
http://marcoslin.github.io/angularAMD
MIT License
734 stars 171 forks source link

Integrating your library with multiple views per state #113

Closed jacobscarter closed 9 years ago

jacobscarter commented 9 years ago

I am trying to lazy load my controllers, I have searched high and low and your repository is the closest thing to what I am looking to do. The problem I have been running into is that I have multiple views per state (I am using ui-router, I have read your entire conversation from issue #9 and carefully viewed the associated plunkr).

I was able to edit your code (which I do not want to do because I would like to be able to update my dependency version with bower) to kind of get it to work. The problem I run into is one controller will load for one of the views and the other wont. Below is my hardcoded version that works perfectly. l am looking to use your library because it is much cleaner but also because it will work better for unit testing.

define(['angular', 'uiRouter'], function(angular, uiRouter){
    var integrateApp = angular.module('integrate.member', ['ui.router']);

    integrateApp.config(function ($stateProvider, $urlRouterProvider, $controllerProvider, $compileProvider, $filterProvider, $provide) {

        window.lazy = {
            controller: $controllerProvider.register,
            directive: $compileProvider.directive,
            filter: $filterProvider.register,
            factory: $provide.factory,
            service: $provide.service
        };

        $urlRouterProvider.otherwise('/');

        $stateProvider
            .state('home', {
                url:'/',
                views: {
                    "top-nav"  : {
                        templateUrl: 'views/home/top-nav.html',
                        resolve : {
                            load : ['$q', '$rootScope', function($q, $rootScope){
                                var d = $q.defer();
                                require(['../app/controllers/header-controller'], function() {
                                    $rootScope.$apply(function(){
                                        d.resolve();
                                    });
                                });
                                return d.promise;
                            }]
                        }
                    },
                    "fullpage": {
                        templateUrl: 'views/home/index.html',
                        resolve : {
                            load : ['$q', '$rootScope', function($q, $rootScope){
                                var d = $q.defer();
                                require(['../app/controllers/home-controller'], function() {
                                    $rootScope.$apply(function(){
                                        d.resolve();
                                    });
                                });
                                return d.promise;
                            }]
                        }
                    }
                }
            }));
    });

    return integrateApp;

});

Here is a controller example:

define(['integrate.member/module'], function (module) {
    lazy.controller('campaign-sidebar-controller', ['$scope', '$state', function ($scope, $state) {

        //controller work

    }]);
});

Any advice on getting this to work would be greatly appreciate. I am very grateful for library you've created and am hoping I'll be able to make it work for what I need!

Thanks.

jacobscarter commented 9 years ago

A little more detail on my app:

index.html

<script type="text/javascript" src="lib/requirejs/require.js" data-main="startup/main.js"></script>

main.js

require.config({
    paths: {
        'angular': '../lib/angular/angular.min',
        'angular-mocks': '../lib/angular-mocks/angular-mocks',
        'jquery': '../lib/jquery/dist/jquery.min',
        'uiRouter': '../lib/ui-router/release/angular-ui-router.min',
        'lazyLoader' : '../lib/lazyLoader',
        'integrate.member': '../app/',
        'Navigation' : '../app/services/navigation-service',
        'leadDownload' : '../app/services/lead-download-service'
    },
    shim: {
        'angular': {
            exports: 'angular'
        },
        'uiRouter':{
            deps: ['angular']
        },
        'angular-mocks': {
            deps: [
                'angular'
            ],
            exports: 'angular.mock'
        }
    },
    deps: ['loader', 'bootstrap']
});

loader.js

define([
    'require',
    'jquery'
], function(require){
    require(['../lib/bootstrap/dist/js/bootstrap.min']);
})

bootstrap.js

define([
    'require',
    'angular',
    'integrate.member/index',
    'bootstrap'
],
function(require, angular) {
    angular.bootstrap(document, ['integrate.member']);
});
marcoslin commented 9 years ago

The issue and code you are using are referencing a very old version of angularAMD. Using the latest version, you can simply do:

...
$stateProvider
      .state('home',{
        url: '/home',
        views: {
          'nav-view': angularAMD.route({
            templateUrl: 'nav_view.html',
            controllerUrl: 'nav_ctrl'
          }),
          'content-view': angularAMD.route({
            templateUrl: 'content_view.html',
            controllerUrl: 'home_ctrl'
          })
        }
      });
...

See the following plunker as example: http://plnkr.co/edit/6uZQKST9mq8skmcqvlo8?p=preview

robson-gilli commented 9 years ago

@marcoslin, is there a way to do what you did but specifying an url as well?