Is it possible to load a controller, it's js file, and a template dynamically based on a route group? Psuedo code which doesn't work:
$routeProvider.when('/:plugin', function(plugin) {
templateUrl: 'plugins/' + plugin + '/index.html',
controller: plugin + 'Ctrl',
resolve: { /* Load the JS file, from 'plugins/' + plugin + '/controller.js' */ }
});
I've seen a lot of questions like this one but none that loads the js file/controller based on a route group.
I managed to solve it inspired by @calebboyd, http://ify.io/lazy-loading-in-angularjs/ and http://weblogs.asp.net/dwahlin/archive/2013/05/22/dynamically-loading-controllers-and-views-with-angularjs-and-requirejs.aspx
Using http://dustindiaz.com/scriptjs
app.js
app.config(function($controllerProvider, $compileProvider, $filterProvider, $provide) {
app.register = {
controller: $controllerProvider.register,
directive: $compileProvider.directive,
filter: $filterProvider.register,
factory: $provide.factory,
service: $provide.service
};
});
Then i register the "load controller by group" route.
$routeProvider.when('/:plugin', {
templateUrl: function(rd) {
return 'plugin/' + rd.plugin + '/index.html';
},
resolve: {
load: function($q, $route, $rootScope) {
var deferred = $q.defer();
var dependencies = [
'plugin/' + $route.current.params.plugin + '/controller.js'
];
$script(dependencies, function () {
$rootScope.$apply(function() {
deferred.resolve();
});
});
return deferred.promise;
}
}
});
controller.js
app.register.controller('MyPluginCtrl', function ($scope) {
...
});
index.html
<div ng-controller="MyPluginCtrl">
...
</div>
You can use RequireJS to do this. Something like:
$routeProvider.when('/:plugin',{
templateUrl: 'plugins/' + plugin + '/index.html',
controller: plugin + 'Ctrl',
resolve: {myCtrl: function($q){
var deferred = $q.defer();
require('myCtrlFile',function(){
deferred.resolve();
});
return deferred.promise;
}}
});
You will also need to register the controller dynamically. By exposing your providers in the app config.
app.config(function($controllerProvider,$compileProvider,$filterProvider,$provide){
app.register =
{
controller: $controllerProvider.register,
directive: $compileProvider.directive,
filter: $filterProvider.register,
factory: $provide.factory,
service: $provide.service
};
});
You controller file might then look like:
define(['app'],function(app){
app.register.controller('myCtrl',MyCtrlFunction);
});
This is just the general idea. I use a similar implementation to the one described here
I also use ui-router. I'm not certain if behavior is the same with ngRoute.
Here is some solution you can do for this code
$routeProvider.when('/:plugin', function(plugin) {
templateUrl: 'plugins/' + plugin + '/index.html',
controller: fun,
loadFrom:"assets/controller/myJsController"// this is our custom parameter we are passing to controller to identify the remote controller file.
});
We will create a parent function for all controller and will call all controller within this function as per defined in route configuration (in loadFrom key of route configuration).
function fun($scope, $http, $location, $timeout, $route) {
$timeout(function () {
var path = $route.current.loadForm;
$http.get("${pageContext.servletContext.contextPath}/resource/controller/" + path + ".js")
.then(function (rsp) {
eval(rsp.data);
});
});
};
in assets/controller/myJsController.js file the code will be as
(function($scope){
//the whole code for controller will be here.
$scope.message="working."
})($scope)
Only thing you have to remember that in parent function you have to use all dependencies.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With