AngularJS: How to embed applications in angular application

I worked on a project that looks more like a structure and has several applications / modules that you can install. See this as the base storage appstore or google.play. This is a kind of intranet application, and all modules can be added to your user account.

the structure is already under development, but now I am enveloping the idea of ​​applications / modules. ( link to proof of concept in development, can be found here )

the application should be somewhat autonomous and not able to suddenly include scripts from the framework. This is entirely possible by structuring them in separate modules:

angular.module('myApp', []); 

however, the application can have templates, scripts, css and can run on a separate server, so I'm looking for the best way to get script (s) and cssfile and dynamically load them into the application when the user starts the app from within the frame.

  • I am currently structuring applications as if they had a main template, for example www.framework.com/apps/myapp/views/app.html , for simplicity I collected scripts into 1 script file for each application, so there is also www.framework.com/apps/myapp/script.js .

The structure contains a template that loads applications, and appController . The template contains this snippet:

 <div data-ng-controller="AppController" data-ng-include="app.appTemplate"> <div>loading...</div> </div> 

this is mainly associated with $scope.app.appTemplate , which is updated when all scripts are loaded, so first it shows the loading template, later after including scripts on the page, it updates app.appTemplate to the aforementioned main application template.

when loading the first index template it works, this template is currently loaded using the appController from the framework, so it uses the $scope framework, not its own script.

I still need to somehow run my own angular application module and allow it myself, without anything in the framework, to "make it work"

I am still figuring out what is the best way to load javascript dependent files (likely to use requrejs or another dependency loader), but currently I don’t know how to “load” the application without working within the appController

EDIT

I created a small demo project to show the problems at hand, the full code is visible on git-hub at the moment when this project makes several difficulties that I will make these less hard-coded when I get the proof of the concept correctly, now it's all about downloading applications in framework. if possible, I can figure out where to get the url and application names from ...

+46
angularjs angularjs-scope
Aug 12 '13 at 10:22
source share
5 answers

You cannot load a module inside another boot module. Bootstrapping compiles the view and associates rootScope with it, traversing it through the DOM and setting up bindings to areas and acting as binding directives to the end. If you do this twice, you will run into problems.

You will probably have to rethink your architecture. I think the word “module” or “application”, as it refers to Angular, is wrong and leads you on the wrong path.

Each "user-installed application" in your application should probably be a truly controlled controller in your application module or registered in the module that your application module refers to. That way, you won’t “run multiple applications”, you would just start one, referring to other modules, and then use the controllers from these modules to control parts of your view on the screen.

What would you do when a new “widget” was installed, you register it in a module file (.js) with a system that will contain a controller named WidgetCtrl, and then, when your page is loaded, you will turn to your module’s widget module applications. From there, it should be available for dynamic assignment to elements using ng-controller and / or ng-include.

Hope this makes sense.

+37
Aug 19 '13 at 15:00
source share

Unlike the currently accepted answer, this is indeed possible.

I worked on a similar problem, and the proposed answer was not acceptable in my case. Earlier I wrote pages with several applications, but this was many years ago, and the applications were independent of each other. There are basically two things:

  • Tell the main application to ignore the child.
  • Download the child.

There is an ng-non-bindable attribute that simply tells AngularJS to ignore the element. This fixes our first problem.

However, when trying to initialize the child; AngularJS throws an error telling you that it is already loaded (at least to me, version 1.2.13). The following trick does the job:

 <div ng-non-bindable data-$injector=""> <div id="bootstrap-me"> <script src="/path/to/app.js"></script> <div ng-include="'/path/to/app.html'"/> </div> </div> 

This solution is not perfect. Ideally, the ng-non-bindable attribute can add the data - $ injector attribute to an element. I am going to make a function and hopefully get a request for AngularJS.




I did not have the opportunity to make a pull request. Obviously, and I have to say that some internal changes have changed, but ng-non-bindable still works in version 1.3.13 using the Ventzy Kunev demo code (thanks again, see the link below).

+26
Mar 05 '14 at 15:57
source share

well, if each helper application is in its own module, you can simply use angular.bootstrap to dynamically load this module. when the URL for a specific application loads, you can get the necessary script (s), and then when the promise is resolved, you can do something line by line:

 // grab a reference to the element where you'll be loading the sub-app var subapp = document.getElementById('subapp-id'); // assuming the script you get back contains an angular module declaration named // 'subapp', manually start the sub-app angular.bootstrap(angular.element(subapp), ['subapp']); 

hope this helps

+4
Aug 19 '13 at 13:42 on
source share

As with UnicodeSnowman above, another potential solution that seems to work for my needs (I built the live Angular editor on the documentation site) is to manually process the boot process with <div id="demos"> , which is separate from the main <div id="myApp"> .

This article has been very helpful for proper operation.

General process

  • Build the main application (I chose manual download, but you can use ng-app for this part)
  • Create a new HTML structure / application (in my case a demo application):
  • Add it to the demos div with user id: someCoolDemoContainer
  • Boostrap newly created application
  • Move it back to the original application (to host / host)

Sample code (not verified, just shows the basic process)

 <div id="myApp"> <h1>Demo</h1> <p>Click the button below to checkout the cool demo!</p> <button ng-click="showDemo()">Show Demo</button> <div class='insertion-point'></div> </div> <div id="demos"> </div> <script type="text/javascript"> /* * Init/bootstrap our main app */ var appContainer = document.getElementById('myApp'); angular.module('myApp', ['myDependency']); angular.bootstrap(appContainer, ['myApp']); // Do lots of other things like adding controllers/models/etc. /* * Init/bootstrap our demo app when the user clicks a button */ function showDemo() { // Append our demo code $('#demos').append('<div id="someCoolDemoContainer">Angular app code goes here</div>'); // Bootstrap the new app var demoContainer = document.getElementById('someCoolDemoContainer'); angular.module('someCoolDemo', ['myDependency']); angular.module('someCoolDemo').controller('myController', function() { ... }); angular.bootstrap(demoContainer, ['someCoolDemo']); // Re-insert it back into the DOM where you want it $('#myApp').find('.insertion-point').append($('#someCoolDemoContainer')); } </script> 
+3
May 7 '15 at 16:41
source share

I know it's pretty long now, but I was looking for a way to embed an AngularJS application in an Angular application and used the answers from this post to do this, so I thought I would post a link here for those looking for a similar solution.

I found two ways to do this, both used to manually load the angularjs application into the ngOnInit component of Angular:

 ngOnInit(): void { // manually bootstrap the angularjs app angular.bootstrap(document.getElementById('ngListApp'), ['list-app']); } 

Or set the ngNonBindable attribute for the item to be loaded:

 <div ngNonBindable #insert> <!-- can insert the angular js template directly here, inside non-bindable element --> <div id="ngListApp" ng-controller="ListController as list"> <input ng-model="inputValue" /> <ul> <li ng-repeat="item in items">{{ item }}</li> </ul> </div> </div> 

Or, insert the angularjs html template into the element in the ngOnInit event handler in the Angular component so that Angular does not try to interpret AngularJS code (especially interpolating AngularJS properties in the DOM with curly braces) at compile time.

 ngOnInit(): void{ // insert angularjs template html here this.div.nativeElement.innerHTML = this.htmlTemplate; // then manually bootstrap the angularjs app angular.bootstrap(document.getElementById('ngListApp'), ['list-app']); } 

Plunker here:

http://plnkr.co/plunks/0qOJ6T8roKQyaSKI

+2
May 01 '18 at 10:09
source share



All Articles