Using OpenLayers with RequireJS and AngularJS

瘦欲@ 提交于 2019-12-07 07:58:52

问题


I'm trying to get an app running that uses both AngularJS and RequireJS. I'm having problems getting my OpenLayers lib to work in this setup.

I set the main AMD-modules in the main.js:

require.config(
    {
        baseUrl: 'scripts',
        paths: {
            // Vendor modules
            angular: 'vendor/angular/angular',
            openLayers: 'vendor/openlayers-debug',
            other modules.....
        },
        shim: {
            angular: {
                exports: 'angular'
            },
            openLayers: {
                exports: 'OpenLayers'
            },
            other modules....
        }
    }
);

require(['openLayers',
        'angular',
        'app',
        'controllers/olMapController',
        'directives/olMap',
        other modules...
    ], function(OpenLayers) {
        return OpenLayers;
    }
);

Then in the angular controller I use for the initialisation of OpenLayers, I try to indicate that openlayers-debug.js is a dependency:

define(['openLayers'],
    function(OpenLayers) {
        controllers.controller('olMapController', ['$scope', function(scope) {
            console.log('Loaded olMapController. OpenLayers version: ' + OpenLayers.VERSION_NUMBER);
        }]);
    }
);

Well, this doesn't work. SOMETIMES the olMapController function is executed, but mostly not. The console then just displays an error stating:

Error: [ng:areq] Argument 'olMapController' is not a function, got undefined

So, I think OpenLayers hasn't finished loading yet, but somehow require thinks it has and continues loading code that depends on OpenLayers, in this case the olMapController. It then can't find its dependency, whereupon Angular returns this error message. Or something like that...? Sometimes something happens that makes OpenLayers load fast enought for it to be present when it is loaded as a dependency. What that is, I can't tell.

I left out other libraries and modules require and define to keep the code readable. I hope the example is still understandable.

Any ideas on what I could do to get openlayers to load well? The error message disappears when I leave the ['openLayers'] dependency out of olMapController.

Thanks in advance for any help.

Best regards, Martijn Senden


回答1:


Sorry this answer will only contain text as your code is too big for a small example.

I would suggest to write a directive that utilizes head.js to load libraries you need at a specific context. One could also think of a directive that initializes openLayers this way.

I guess your error is a timing problem, because the require.js and angular.js module loading gets out of sync - more precisely there seems to be no sync at all between them.

update
To repeat my comment which lastly helped to lead the OP in the right direction:

You have to decide which framework gives the tone. If you go with requireJS, then require everything and bootstrap angular manually. (Remove ng-app="" from index.html) and do `angular.bootstrap()´ when requirejs has completed. So the problem most likely is, that angular starts too early.




回答2:


Well, just for reference my final solution. The comment by angabriel set me off in the right direction.

Like i said, I'm using the domReady module provided by RequireJS to bootstrap Angular. This is still being called to early, because OpenLayers isn't loaded yet when angular starts. RequireJS also provides a callback property in require.config. This is a function that is triggered when all the dependencies are loaded. So I used that function to require the angular bootstrap module. My config now looks like this:

require.config(
    {
        baseUrl: 'scripts',
        paths: {
            // Vendor modules
            angular: 'vendor/angular/angular',
            domReady: 'vendor/domReady',
            openLayers: 'vendor/openlayers-debug',
            etcetera....

        },
        shim: {
            angular: {
                deps: ['jquery'],
                exports: 'angular'
            },
            openLayers: {
                exports: 'OpenLayers'
            },
        },
        deps: ['angular',
            'openLayers',
            'app',
            'domReady',
            'controllers/rootController',
            'controllers/olMapController',
            'directives/olMap'
        ],
        callback: function() {
            require(['bootstrap']);
        }
    }
);

And the bootstrap module looks like this:

define(['angular', 'domReady', 'app'], function(angular, domReady) {
    domReady(function() {
        angular.bootstrap(document, ['GRVP']);
    });
});

Thanks for the help. @angabriel: I upvoted your comment. It's not possible to accept a comment as an answer, is it? Your initial answer wasn't really the answer to my question, but the comment helped a lot...

Regards, Martijn



来源:https://stackoverflow.com/questions/21410284/using-openlayers-with-requirejs-and-angularjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!