23

I have two ng-app like ;

<div ng-app="app1" >
    somexpression   
    <div ng-app="app2">
        some more expression
    </div>
</div>

is there any way to make it work? when I make a nested ng-app it doesn't work

I know that I can use two different controller but I don't want to use two controllers ---- EDIT -----

The thing is;

 angular.module('AppName', [
            'angular-carousel'
        ])

SO I need somehow to change this ng-app to directive

Juan Carlos Oropeza
  • 47,252
  • 12
  • 78
  • 118
zyrag
  • 353
  • 1
  • 3
  • 17
  • 2
    Your app can include references to other modules which may contain services, controllers, directives etc. You just need to have one main app that references the others - what exactly are you trying to do? – link64 Mar 21 '14 at 01:52
  • Did you try it? What problems did you have? When creating a custom directive; one approach is to add that directive onto it's own module. Then you can pass the module name as an argument to a module and access those directive inside the other module. UI Bootstrap is implemented this way. that is kind of like using one app inside another. – JeffryHouser Mar 21 '14 at 01:54
  • It is possible thought to have two apps inside one page... but it's messy to manage routing when you do that. You can manually bootstrap two apps inside different elements, even with their own ng-view for each of them, but as I said, routing is a pain in the ass, because both apps use the same location path, but different routeProviders – doodeec Mar 21 '14 at 07:47
  • The pain may be solved by overriding $window.location.hash (for non html5Mode) per ngApp. – avalez Nov 15 '17 at 22:04

3 Answers3

27

From the AngularJS document, the answer is no

http://docs.angularjs.org/api/ng/directive/ngApp

AngularJS applications cannot be nested within each other.

And if not nested, then it's OK, someone already asked this question, refer here:AngularJS Multiple ng-app within a page and the AnguarJS document

http://docs.angularjs.org/api/ng/directive/ngApp

Only one AngularJS application can be auto-bootstrapped per HTML document. The first ngApp found in the document will be used to define the root element to auto-bootstrap as an application. To run multiple applications in an HTML document you must manually bootstrap them using angular.bootstrap instead.

Community
  • 1
  • 1
xiaoboa
  • 1,953
  • 14
  • 18
14

I found one tricky solution for this problem. The idea is that the "host" application have to somehow jump over the root element of nested application. I used directive for this:

    angular.module("ng").directive("ngIsolateApp", function() {
        return {
            "scope" : {},
            "restrict" : "AEC",
            "compile" : function(element, attrs) {
                // removing body
                var html = element.html();
                element.html('');
                return function(scope, element) {
                    // destroy scope
                    scope.$destroy();
                    // async
                    setTimeout(function() {
                        // prepare root element for new app
                        var newRoot = document.createElement("div");
                        newRoot.innerHTML = html;
                        // bootstrap module
                        angular.bootstrap(newRoot, [attrs["ngIsolateApp"]]);
                        // add it to page
                        element.append(newRoot);
                    });
                }
            }
        }
    });

Example simple app:

// module definition
    angular.module("testMod1",[])
        .service("moduleService", function ModuleService() {
            this.counter = 0;
            this.getCounter = function() {
                return this.counter;
            };
            this.incCounter = function() {
                this.counter += 1;
            }
        })
        .controller("ModuleCtrl", function(moduleService) {
                this.getValue = function() {
                    return moduleService.getCounter();
                };
                this.incValue = function() {
                    moduleService.incCounter();
                };
            });

Now in the markup we can use the ng-isolate-app:

<!-- App instance 1 -->
<body ng-app="testMod1">

<div ng-controller="ModuleCtrl as ctrl">
    {{ctrl.getValue()}}
    <button ng-click="ctrl.incValue()">Click</button>
    <!-- App instance 2 -->
    <div ng-isolate-app="testMod1">
        <div ng-controller="ModuleCtrl as ctrl">
            {{ctrl.getValue()}}
            <button ng-click="ctrl.incValue()">Click</button>
            <!-- App instance 3 -->
            <div ng-isolate-app="testMod1">
                <div  ng-controller="ModuleCtrl as ctrl">
                    {{ctrl.getValue()}}
                    <button ng-click="ctrl.incValue()">Click</button>
                </div>
            </div>
        </div>
    </div>
</div>
</body>

Working example on plnkr

This works in simple cases, I do not know how this will work on complex applications.

Mars Robertson
  • 12,673
  • 11
  • 68
  • 89
majo
  • 381
  • 3
  • 8
0

You can't use one ng-app inside another one in angularjs. because AngularJS applications cannot be nested within each other.

https://docs.angularjs.org/api/ng/directive/ngApp

Sumit
  • 1