This question already has answers here:
How to run two separate Angular js apps in the same page
(3 answers)
Closed 8 years ago.
I am trying to get a second AngularJS App and Controller working but it seems the first one runs but the second never does. It seems to work if I make a single app with 2 controllers. Any insights would be appreciated. Thanks!
JS
var app1 = angular.module("myapp1", []);
app1.controller('Ctrl1', function($scope){
$scope.variable = "Ctrl1 Working";
});
var app2 = angular.module("myapp2", []);
app2.controller('Ctrl2', function($scope){
$scope.variable = "Ctrl2 Working";
});
HTML
<div ng-app="myapp1" ng-controller="Ctrl1">
<p>{{variable}}</p>
</div>
<div ng-app="myapp2" ng-controller="Ctrl2">
<p>{{variable}}</p>
</div>
JSFiddler: http://jsfiddle.net/paullyvenne/8Ekv5/8/
The main problem here is that AngularJS can't boostrap several applications in just one HTML file.
Here i let you a link to AngularJS site that explain that.
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.
Instead of have several ng-app that mean several AngularJS Application, you can design a structure of multiples modules organized by feature. If you wanna know about it please see the links below:
Coderwall
clintberry.com
Henriquat.re
Related
Need help in knowing how to use AngularJS in Salesforce Lightning and VisualForce pages?
I do know that it has to be used using static resource but need step by step details in using it.
Well, when talking about AngularJS, I believe you are talking about the version 1.x, because the version 2.0, which is currently 6.0 needs to be used in a different way compared to the earlier version.
For Angular 1.x, I am listing down the steps here:
The very first step is to download the latest version of AngularJS. You can get that here.
https://angularjs.org/
Zip the AngularJS file and create a Static Resource, so that you can reference it in your pages. In case, you want to know how to create a static resource in Salesforce, refer SF documentation.
https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_resources_create.htm
(You also have an option of directly referencing the CDN file in your VF pages, however, it is recommended that you should go for Static resources.)
Now, to get AngularJS in action, you have to do something called as “bootstrapping” your app.
This can be done in 2 ways:
Use “ng-app” directive. (NOTE:You can only have one ng-app directive in your HTML document. If more than one ng-app directive appears, the first appearance will be used.)
And the second way is manual bootstrapping. You can refer to this blog to know more about it.
http://blogs.quovantis.com/process-to-use-manual-bootstrapping-in-angularjs-with-examples/
You can use the following code to see manual bootstrapping in action.
<apex:page showHeader="true" sidebar="true">
<apex:includeScript value="{!URLFOR(<your-static-resource-name>,'angular.min.js')}">
<div id="demo" ng-controller="demoAngularController">
{{testVar}}
</div>
<script>
var demoModule = angular.module('demo', []);
demoModule.controller('demoAngularController', function ($scope) {
$scope.testVar = 'Prem';
});
angular.bootstrap(document.getElementById("demo"),['demo']);
</script>
Make sure you replace the static resource name with actual name that you created in the system.
I have added a code snippet as well.
var app = angular.module('demo', []);
app.controller('demoAngularController',function MyController($scope) {
$scope.testVar = 'Prem';
});
angular.bootstrap(document.getElementById("demo"),['demo']);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div id="demo">
<div ng-controller='demoAngularController'>
<h1>Hello, {{ testVar }}!</h1>
</div>
</div>
For Angular 2.0
In case, you want to learn the usage of Angular2.0 (or Angular6.0 as known currently), you may look at this tutuorial and let me know your feedback.
https://premjpal.wordpress.com/2018/09/06/getting-started-with-angular6-in-salesforce/
Happy coding!
In the tutorial:
http://www.w3schools.com/angular/angular_modules.asp
"A module is created by using the AngularJS function angular.module."
However, the module is already existent in the div tag defined before
<div ng-app="myApp">...</div>
Then what is the significance of the quoted statement above?
Danke / Dhonnobad (I hope it doesn't get deleted :) )
angular.module in fact creates module - your app configuration, so when angular process html and found ng-app directive - it will instantiate your app using that configuration.
In terms of i.e. Java you can say angular.module creates Class,
when <div ng-app="myApp"> creates instance.
The module is a container for the application controllers and directives, in general.
Incase you mention in index.html as,
<div ng-app="myapp"> ..</div>
And you maintain a separate javascript file for controller codes and directive codes, to avoid messing up in html file in between script tags, consider in index.js, You give it as
var app=angular.module("myapp",[])
And then you can add controllers like ,
app.controller("mycontroller",function($scope){
//javascript code
});
This is how controller functions act upon module specified. Hope this suffice.
Is there a way to define an angular module inside another module ? I have a template in my web application which is called for almost every page of the application. In the template definition I set the ng-app. So for this ng-app I can declare the modules I need in all pages of the application (or almost every page). Now there are some modules I want to add only on specific pages. The problem is that in those pages I already have the ng-app of the template.
So is there a way to keep the ng-app as some kind of root ng-app which declared the modules I need everywhere and then add specific modules inside specific pages too ?
That means is it possible to do something like this:
<div ng-app="rootApp">
<div ng-app="specificApp">
...
</div>
</div>
The rootApp contains the module that are declared in my template, that are use in all the pages, and the specifiApp contains the modules I need only in one specific page.
Thanks !
[EDIT] Bootstrap attempt:
var reportHolidaysByEmployeeApp = angular.module('reportHolidaysByEmployeeApp', ['fitnetApp', 'ui.bootstrap']);
angular.bootstrap(document.getElementById("reportHolidaysByEmployeeApp"), ['reportHolidaysByEmployeeApp']);
reportHolidaysByEmployeeApp.controller('ReportHolidaysByEmployeeCtrl', function($scope, $filter, $timeout) {
fitnetApp is the global Module I load on the html tag in every page
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. --
http://docs.angularjs.org/api/ng.directive:ngApp
See also
https://groups.google.com/d/msg/angular/lhbrIG5aBX4/4hYnzq2eGZwJ
http://docs.angularjs.org/api/angular.bootstrap
If you are having separate controllers for your pages[views] , add dependency in your controller module to [rootApp] or [spcificApp] as your page needs.
$routeProvider.when('/view1',{
template:
controller:view1controller
})
if u need rootApp as dependency in view1 page
in your controller module
angular.module('GlobalCtrl',['rootApp'])
.controller('view1controller')
'
You cannot have two ng-app in a single web page.
If you need to add dependency module on specific page use
angular.module('reportHolidaysByEmployeeApp').requires.push('thirdpartymodule');
This will dynamically inject dependency in your already running angular application.
if you have the following:
<html ng-app="outerApp">
<head ng-app="innerApp"></head>
<script>
var outerApp = angular.module("outerApp", []);
var ACtrl = outerApp.controller("ACtrl", function($scope){console.log($scope.name);});
var BCtrl = outerApp.controller("BCtrl",function($scope){console.log($scope.name});
var CCtrl = innerApp.controller.("CCtrl", function($scope){ console.log($scope.name);});
var innerApp = angular.module("innerApp", []);
</scope>
Is this ok? is angular a global variable that will work for declaring modules out of both innerApp and outerApp? Also are there limits to number of ng-app's on a page? And do both ACtrl, and BCtrl have reference to the same $scope?
Thanks
This won't work because:
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.
See documentation
$rootscope,$scope are conceptually global variables, whom you can implement to achieve as global variables for sharing data between the modules,directives,controllers,views.
you should read conceptually DI(Dependency Injection) and how the conceptual framework implements in angular. you can inject the dependencies.
angular.module('modulename',[]);
[] is an array in which you define that module is dependant on the other module. in Other words.
Angular framework concepts works the injectable way DI(Dependency Inject).
however i strongly suggest you, what you trying to achieve is the right path is, you should make a simple custom directive and inject it as a dependency in the angular app.
New to Angular. I feel like I'm missing something obvious: Shouldn't I easily be able to run to separate AngularJs apps (modules) in the same html page? Something like this:
<section ng-app="HelloWorldApp" ng-controller="HelloWorldController">
Hello {{name}}!
</section>
<br />
<section ng-app="MyNameIsApp" ng-controller="MyNameIsController">
My Name is {{FirstName}} {{LastName}}!
</section>
Javascript:
var HelloWorldApp = angular.module('HelloWorldApp', []);
HelloWorldApp.controller('HelloWorldController', function($scope) {
$scope.name = 'World';
});
var MyNameIsApp = angular.module('MyNameIsApp', []);
MyNameIsApp.controller('MyNameIsController', function($scope) {
$scope.FirstName = 'John';
$scope.LastName = 'Smith';
});
This only runs the first module, while the second doesn't appear to do anything. I want to do this so that I can build reusable, encapsulated directives for multiple pages that don't have to name their modules the same thing.
Live Example: http://plnkr.co/edit/cE6i3ouKz8SeQeA5h3VJ
We ended up building small hierarchy of modules, however my original question can done, with just a bit of work (see below).
It is possible, but it requires a little bit coding by hand. You need to bootstrap the angular apps on your own. Don't worry, it is not that complicated
Do not add ng-app attributes in your HTML
Make sure you can fetch the DOM elements holding the app
When DOM is loaded you need to start the apps on your own: angular.bootstrap( domElement, ['AppName']);
Fork of you plunker which works: http://plnkr.co/edit/c5zWOMoah2jHYhR5Cktp
According to the Angular docs for ngApp:
Use this directive to auto-bootstrap an application. Only one
directive can be used per HTML document. The directive designates the
root of the application and is typically placed at the root of the
page.
Seems it's by design.
You can specify any nested apps in the module def of the main one.
angular.module("myapp", ['statusapp', 'tickerapp']).controller(....
and in a separate file, you have the other apps defined. We're using a template engine which hides some of this, but you'll end up with HTML that contains nested ng-apps and javascript for each one that defines the module/controller. The code above is the trick to getting more than one bootstrapped.