AngularJS2015. 12. 3. 17:52
반응형
Posted by 1010
AngularJS2015. 12. 3. 17:29
반응형


angular.min.js


jquery.min.js


ng-grid.min.css


ng-grid.min.js




<!doctype html>

<html>

<head>

<title>Hello AngularJS</title>

<link href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">

<link href="../css/ng-grid.min.css" rel="stylesheet">

<style type="text/css">

.gridStyle {

border: 1px solid rgb(212, 212, 212);

width: 100%;

height: 700px;

font: 12px Tahoma;

color: #777;

}

</style>

</head>

<body>

<div ng-app="app01">

<div ng-controller='appctrl01'>

<div class="gridStyle" ng-grid="gridOptions"></div>

</div>

</div>

<!-- <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script> -->

<script src="../js/jquery.min.js"></script>

<script src="../js/angular.min.js"></script>

<script src="../js/ng-grid.min.js"></script>

<script src="../js/ui-grid.js"></script>

<script type="text/javascript">

var newsModule = angular.module('app01', [ 'ngGrid' ]);

newsModule.controller('appctrl01', fnNewsCtrl);

function fnNewsCtrl($scope, $http) {

$http.get('https://api.getevents.co/event?&lat=41.904196&lng=12.465974').success(

function(data)

{

$scope.successData = data.events;


});

$scope.gridOptions = {

data : 'successData',

enableCellSelection : false,

enableRowSelection : false,

enableCellEdit : false,

columnDefs : [

             {field : 'id',displayName : 'id',enableCellEdit : true},

             {field : 'name',displayName : 'name',enableCellEdit : true},

             {field : 'city_meta.area',displayName : 'city_meta.area',enableCellEdit : true},

             {field : 'city_meta.area_code',displayName : 'city_meta.area_code',enableCellEdit : true},

             {field : 'source_name',displayName : 'source_name',enableCellEdit : true},

             {field : 'image_large_url',displayName : 'image_large_url',enableCellEdit : true},

             {field :'image_large_url', displayName:'image_large_url', cellTemplate: '<img ng-src="{{row.getProperty(\'image_large_url\')}}"></img>'}

]

};

}

</script>

</body>

</html>





Posted by 1010
AngularJS2015. 12. 3. 11:21
반응형
Learn different ways on how to define multiple angular apps on single page.
Recently in my previous post, I have posted about Different ways of bootstrapping AngularJS app, where you can either auto-bootstrap using ng-app attribute or manually bootstrap using angular.bootstrap function. And also mentioned in angular interview questions that "Only one AngularJS application can be auto-bootstrapped per HTML document." Which means that your page can only have single ng-app attribute. If you put multiple ng-app attribute, only first will be considered and the rest will be ignored.
 

You may also like:Let's see with an example. In the below code, there are 2 ng-app present on the page.
<div ng-app="firstApp">
  <div ng-controller="FirstController">
    <p>1: {{ desc }}</p>
  </div>
</div>

<div ng-app="secondApp">
  <div ng-controller="SecondController">
    <p>2: {{ desc }}</p>
  </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.7/angular.js"></script>
<script type="text/javascript">
var firstApp = angular.module('firstApp', []);
firstApp.controller('FirstController', function($scope) {
    $scope.desc = "First app.";
});

var secondApp = angular.module('secondApp', []);
secondApp.controller('SecondController', function($scope) {
    $scope.desc = "Second app.";
});
</script>
And below is the output. Out of 2 ng-app present on the page, the first one gets initialized and works as expected. Output also shows the same.
1: First app.
2: {{ desc }}

Then how can you define 2 different angular apps on the same page? Well, there are a couple of ways to implement this.

Manually bootstrapping each app

You can manually bootstrap both the application using angular.bootstrap() as we have seen in Different ways of bootstrapping AngularJS app.
var firstApp = angular.module('firstApp', []);
firstApp.controller('FirstController', function($scope) {
   $scope.desc = "First app. ";
});

var secondApp = angular.module('secondApp', []);
secondApp.controller('SecondController', function($scope) {
  $scope.desc = "Second app. ";
});

var dvFirst = document.getElementById('dvFirst');
var dvSecond = document.getElementById('dvSecond');

angular.element(document).ready(function() {
   angular.bootstrap(dvFirst, ['firstApp']);
   angular.bootstrap(dvSecond, ['secondApp']);
});
Since we are bootstrapping them manually, make sure to remove ng-app attribute from the HTML page.
Manually bootstrapping second app

You can also manually bootstrap the second app, where the first app gets initialized via ng-app
var firstApp = angular.module('firstApp', []);
firstApp.controller('FirstController', function($scope) {
   $scope.desc = "First app. ";
});

var secondApp = angular.module('secondApp', []);
secondApp.controller('SecondController', function($scope) {
  $scope.desc = "Second app. ";
});

var dvSecond = document.getElementById('dvSecond');

angular.element(document).ready(function() {
   angular.bootstrap(dvSecond, ['secondApp']);
});
So make sure that there is ng-app present on the page for first app.
Using dependency injection to inject both in root app

You can define a root level app using ng-app and then inject both the apps as module in root app.
var rootApp = angular.module('rootApp', ['firstApp','secondApp']);
var firstApp = angular.module('firstApp', []);
firstApp.controller('FirstController', function($scope) {
   $scope.desc = "First app. ";
});

var secondApp = angular.module('secondApp', []);
secondApp.controller('SecondController', function($scope) {
  $scope.desc = "Second app. ";
});
And make sure any parent node (body/Parent div) is assigned with ng-app=rootApp".


Posted by 1010
AngularJS2015. 12. 3. 11:17
반응형

The answer is NO. The ng-app directive is used to auto-bootstrap an AngularJS application. And according to AngularJS Documentation, only one AngularJS application can be auto-bootstrapped per HTML document. I'd like to quote a section from the documentation here:

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. AngularJS applications cannot be nested within each other.

I'm going to show three approaches, latter two being similar, to deal with the issue.

Before that let's take a look what the actual problem is.
<!DOCTYPE html>

<html>
<head>
<title>Multiple ngApp does not work</title>
</head>

<body>
       <div ng-app="firstApp">
              <div ng-controller="FirstController">
                 <p> 1# {{ name }} </p>
              </div>
       </div>

       <div ng-app="secondApp">
              <div ng-controller="SecondController">
                 <p> 2# {{ name }} </p>
              </div>
       </div>

       <script src="angular.js"></script>
       <script type="text/javascript">
              
            var firstApp = angular.module('firstApp', []);
            firstApp.controller('FirstController'function($scope) {
            
                 $scope.name = "I'm the first app.";
            });

            var secondApp = angular.module('secondApp', []);
            secondApp.controller('SecondController'function($scope) {
            
                $scope.name = "I'm the second app.";
            });
       </script>
</body>
</html>

As you can see, we defined two separate ng-app directives named firstApp and secondApp. And we also defined two controllers one for each ng-app module and each having its own scope variable name. As the documentation states, only the first ng-app module is auto-bootstrapped. So, in this case, only the firstApp module works as expected while the secondApp module does not. As a consequence, the browser renders the above page as follows:


1# I'm the first app.
2# {{ name }} 

Now that we discussed the problem, let's move ahead and see how to use alternatives.

Method 1: Injecting modules as dependencies of the root app

The idea here is to define only one top level ng-app in a root element like in <html> or <body>, define other two as modules and inject them as dependencies of the root app.
<!DOCTYPE html>

<html>
<head>
       <title>Injecting modules as dependencies of the root app </title>
</head>

<body ng-app="rootApp">

<div id="firstApp">
       <div ng-controller="FirstController">
              <p>1# {{ name }}</p>
       </div>
</div>

<div id="secondApp">
       <div ng-controller="SecondController">
              <p>2# {{ name }}</p>
       </div>
</div>

<script src="angular.js"></script>
<script type="text/javascript">

    // passing the two modules as dependencies of the root module
    var rootApp = angular.module('rootApp', ['firstApp','secondApp']);

    var firstApp = angular.module('firstApp', []);
         firstApp.controller('FirstController'function ($scope) {
         $scope.name = "I'm the first app.";
    });

    var secondApp = angular.module('secondApp', []);
    secondApp.controller('SecondController'function ($scope) {
         $scope.name = "I'm the second app.";
    });      

</script>
</body>
</html>
This will give the desired result:

1# I'm the first app.
2# I'm the second app.


Method 2: Manual bootstrapping the second module

In this method, we are going to leave the first ng-app as it is so that it is auto-bootstrapped by Angular. Whereas for the second ng-app, we're going to a manual bootstrapping method.
<!DOCTYPE html>

<html>
<head>
      <title>Manual bootstrapping the second module</title>
</head>

<body>
       <div ng-app="firstApp">
              <div ng-controller="FirstController">
                     <p>1# {{ name }}</p>
              </div>
       </div>

       <!-- using id attribute instead of ng-app -->
       <div id="secondApp">
              <div ng-controller="SecondController">
                     <p>2# {{ name }}</p>
              </div>
       </div>

<script src="angular.js"></script>
<script type="text/javascript">
      
       var firstApp = angular.module('firstApp', []);
       firstApp.controller('FirstController'function($scope) {

              $scope.name = "I'm the first app.";
       });

       var secondApp = angular.module('secondApp', []);
       secondApp.controller('SecondController'function($scope) {

              $scope.name = "I'm the second app.";
       });

       // manually boostrapping the second app
       var secondDiv = document.getElementById('secondApp');

       angular.element(document).ready(function() {
              angular.bootstrap(secondDiv, [ 'secondApp' ]);
       });
</script>
</body>
</html>

Method 3: Manual bootstrapping both modules

As I already mentioned, this method is similar to the previous one. Here, we don't rely on Angular's auto-bootstrapping to initialize the modules. We'll use manual bootstrapping method to initialize both modules as depicted in the example below:
<!DOCTYPE html>

<html>
<head>
      <title>Manual boostrapping both modules</title>
</head>

<body>
       <!-- using id attribute instead of ng-app -->
       <div id="firstApp">
              <div ng-controller="FirstController">
                     <p>1# {{ name }}</p>
              </div>
       </div>

       <!-- using id attribute instead of ng-app -->
       <div id="secondApp">
              <div ng-controller="SecondController">
                     <p>2# {{ name }}</p>
              </div>
       </div>

<script src="angular.js"></script>
<script type="text/javascript">
       var firstApp = angular.module('firstApp', []);
       firstApp.controller('FirstController'function($scope) {

              $scope.name = "I'm the first app.";
       });

       var secondApp = angular.module('secondApp', []);
       secondApp.controller('SecondController'function($scope) {

              $scope.name = "I'm the second app.";
       });

       var firstDiv = document.getElementById('firstApp');
       var secondDiv = document.getElementById('secondApp');

       // manually boostrapping the second app
       angular.element(document).ready(function() {
              angular.bootstrap(firstDiv, [ 'firstApp' ]);
              angular.bootstrap(secondDiv, [ 'secondApp' ]);
       });
</script>
</body>
</html>


Posted by 1010