Inject module dependency (like plugin) only if needed AngularJS
Asked Answered
O

5

9

I have 2 pages (I don't use the angular's routing - This constraint).

In one of them I want to use the directive ui-grid like in this demo:

var app = angular.module('myApp', ['ui.grid']);
app.controller('mainCtrl', function($scope) {
  $scope.myData = [
    {
        "firstName": "Cox",
        "lastName": "Carney",
        "company": "Enormo",
        "employed": true
    },
    {
        "firstName": "Lorraine",
        "lastName": "Wise",
        "company": "Comveyer",
        "employed": false
    },
    {
        "firstName": "Nancy",
        "lastName": "Waters",
        "company": "Fuelton",
        "employed": false
    }
  ];
});
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.js"></script>
<script src="http://ui-grid.info/release/ui-grid-unstable.js"></script>
<link rel="stylesheet" href="http://ui-grid.info/release/ui-grid-unstable.css" type="text/css">

<div ng-app="myApp">
  <div ng-controller="mainCtrl">
    <div id="grid1" ui-grid="{ data: myData }" class="grid"></div>
  </div>
</div>

My question is if there is a way to not inject the ui-grid dependency to the app in any case but only when I need it.

Something like:

app.controller('mainCtrl', function($scope) {
   app.$inject('ui-grid');
});

Update

I tried to do:

var ui_grid = $injector.get('ui-grid');

But I've got an error:

Unknown provider: ui-gridProvider <- ui-grid

http://errors.angularjs.org/1.2.26/$injector/unpr?p0=ui-gridProvider%20%3C-%20ui-grid

Olivier answered 17/12, 2015 at 8:3 Comment(8)
Duplicate of https://mcmap.net/q/814403/-angularjs-runtime-dependency-injection ?Bryon
@AT no it's not. My question is about using another module and his directives in the view not in the controller.Olivier
I assume also a dupe of #29618403 & #27722030. In Mosh’s case it’s a directive not a serviceDisproportion
@AntonStrogonoff No, it's not. Did you see my comment to A T? It's the same. I don't need to inject a service or factory. I need to inject a module. Can you share with me a working fiddle with solution like in your attached question?Olivier
@MoshFeu I don’t think injector would help you with modules indeed, can’t help here. Note that in your second code block example you’re showing how you want to inject a directive, not a module. It’s in general confusing as to what is the goal that you’re trying to achieve.Disproportion
@AntonStrogonoff ya I know, I just want to mention that I tried like A t's answer so people will not offer solutions like this. Thanks anyway ;)Olivier
Why not make your app dependencies a variable that is a array, then just based on some conditions (such as which page) decide what modules to add to the app? You can not directly inject modules into a controller as you are trying to do, since the directive in the view needs that module to already be loaded.Fetishist
Thanks @Fetishist that's what I do now. I'm looking for the the "right" way to do this.Olivier
C
5

Core Angular API does not provide this feature. ocLazyLoad is the popular library for lazy loading of modules and components in Angular.

You can find more info on their page: https://oclazyload.readme.io

or the GitHub repository: https://github.com/ocombe/ocLazyLoad

Caritta answered 22/12, 2015 at 14:5 Comment(0)
N
3

Core Angular API does provide this feature, simply use 'requires' property of module @ Properties section @ https://code.angularjs.org/1.4.7/docs/api/ng/type/angular.Module

var app = angular.module('myApp');

//Page 1 JS
//change below statement as per requirement in different pages
app.requires = ['ui.grid'];
app.controller('mainCtrl1', function($scope) {

}

//Page 2 JS
app.requires = ['ngResource', 'ui.bootstrap', 'ui.calendar'];
app.controller('mainCtrl2', function($scope) {

}

ocLazyLoad is also good solution, but I guess 'requires' property will solve your problem without much effort.

Napper answered 21/7, 2016 at 10:34 Comment(0)
D
1

In my project I dynamically bootstrap angular modules using angular.bootstrap(). I have several pages with different sets of modules.

Example:

var app = angular.module('demo', [])
.controller('WelcomeController', function($scope) {
  $scope.greeting = 'Welcome!';
});
angular.bootstrap(document, ['demo']);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-controller="WelcomeController">
  {{greeting}}
</div>
Divergence answered 28/12, 2015 at 13:22 Comment(0)
B
0

$injector is used to retrieve object instances as defined by provider, instantiate types, invoke methods, and load modules.

var $http = $injector.get('$http');

To complete your use-case:

app.controller('mainCtrl', function($scope, $injector) {
    $scope.myData = [];
    if($scope.loadGrid) {
        var ui_grid = $injector.get('ui-grid');
        ui_grid.load($scope.myData); //`.load` is just a guess, obviously read your docs
    }
});

For more information see:

Bryon answered 17/12, 2015 at 8:6 Comment(4)
That if I want to use the $http in the controller. My question is about inject another module with directives.Olivier
Yes, $http is just an example. Replace $http with whatever other module you like.Bryon
.load is just a guess, obviously read your docs ui-grid I don't think that you can inject module and use it like this. Also, an exception is thrown (see the update of my question)Olivier
Who updavote this answer? It's not even works regardless of the specific module. See the update of my question.Olivier
M
0

In a angularJS for injecting module you should inject it after your module name as you did.

But you have few steps to can use it:

  1. Install it with this 2 way npm or bower like below:

    npm install angular-ui-grid

    bower install angular-ui-grid

  2. Then add a <script> to your index.html:

    <link rel="stylesheet" type="text/css"href="/bower_components/angularui-grid/ui-grid.css" />
    <script src="/bower_components/angular-ui-grid/ui-grid.js"></script>
    
    • If you use npm, you should change the source path to/node_modules/.

After this steps each module you can have access to you module like below:

angular.module('my.module', ['ui.grid']).

Mervin answered 24/12, 2015 at 16:21 Comment(2)
Thank you for your answer but it's not what I asked. I know how to inject module to my app. My question is about dynamic injection. Please read the question again.Olivier
sorry because of my miss understanding! you can check angularjs-requirejs-lazy-controllers. maybe be useful.Mervin

© 2022 - 2024 — McMap. All rights reserved.