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

4
  • 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? Commented Mar 21, 2014 at 1: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. Commented Mar 21, 2014 at 1: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 Commented Mar 21, 2014 at 7:47
  • The pain may be solved by overriding $window.location.hash (for non html5Mode) per ngApp. Commented Nov 15, 2017 at 22:04

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

Comments

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.

4 Comments

This is the answer real developers want to hear!
@majo please can you check the link for the jsFiddle
Well done. Successfully using in production. Much love!
nice trick. I just created an element, bootstrap it, and finally append to the DOM.
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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.