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

Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
  • Duplicate of http://stackoverflow.com/q/13724832 ? – A T Dec 17 '15 at 08:22
  • @AT no it's not. My question is about using another module and his directives in the `view` not in the `controller`. – Mosh Feu Dec 17 '15 at 08:26
  • I assume also a dupe of http://stackoverflow.com/questions/29617903/conditionally-inject-angular-module-dependency & http://stackoverflow.com/questions/27721530/conditional-injection-of-a-service-in-angularjs. In Mosh’s case it’s a directive not a service – Anton Strogonoff Dec 17 '15 at 08:36
  • @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? – Mosh Feu Dec 17 '15 at 08:39
  • @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. – Anton Strogonoff Dec 17 '15 at 08:53
  • @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 ;) – Mosh Feu Dec 17 '15 at 08:59
  • 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. – jjbskir Dec 22 '15 at 15:16
  • Thanks @jjbskir that's what I do now. I'm looking for the the "right" way to do this. – Mosh Feu Dec 22 '15 at 16:53

5 Answers5

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

S.Klechkovski
  • 4,005
  • 16
  • 27
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.

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>
Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
Mikalai
  • 1,515
  • 8
  • 21
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:

A T
  • 13,008
  • 21
  • 97
  • 158
  • That if I want to use the `$http` in the controller. My question is about inject another `module` with directives. – Mosh Feu Dec 17 '15 at 08:13
  • Yes, `$http` is just an example. Replace `$http` with whatever other module you like. – A T Dec 17 '15 at 08:14
  • _`.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) – Mosh Feu Dec 17 '15 at 08:28
  • Who updavote this answer? It's not even works regardless of the specific module. See the **update** of my question. – Mosh Feu Dec 17 '15 at 08:32
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']).

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
  • 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. – Mosh Feu Dec 24 '15 at 19:59
  • 1
    sorry because of my miss understanding! you can check [angularjs-requirejs-lazy-controllers](https://github.com/matys84pl/angularjs-requirejs-lazy-controllers). maybe be useful. –  Dec 24 '15 at 20:13