AngularJS:如何在angular度应用程序中嵌套应用程序

我一直在做一个更像框架的项目,并且有几个可以安装的应用程序/模块。 看到它像一个基本的appstore或google.play商店。 这是一个内联网应用程序,所有模块可以添加到您的使用帐户。

该框架已经在开发中,但是现在我正在围绕着应用程序/模块的想法。 ( 链接到开发中的概念certificate,可以在这里find )

一个应用程序应该是有点独立的,不能突然从框架中包含脚本,这是完全可能的,通过在不同的模块中构build它们,如下所示:

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

然而,一个应用程序可以有模板,脚本,CSS,它可以运行在一个单独的服务器上,所以我寻找最好的方式来获取脚本和CSS文件(S)并dynamic地加载到应用程序当用户从框架内启动app时。

  • 目前我正在构build应用程序,就好像他们有一个主要的模板,例如www.framework.com/apps/myapp/views/app.html ,为了简单起见,我将脚本绑定到每个应用程序的一个脚本文件中,所以也有包括一个www.framework.com/apps/myapp/script.js

该框架包含一个加载应用程序的模板和一个appController 。 该模板包含这一块:

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

这基本上绑定到所有脚本加载后更新的$scope.app.appTemplate ,所以首先显示一个加载模板,稍后在页面中包含脚本后,它将app.appTemplate更新到上面提到的主模板应用。

当加载第一个索引模板的时候,这个模板当前是从框架中加载了AppController的,所以它使用框架的$scope而不是它自己的脚本。

我仍然必须以某种方式启动应用程序自己的angular度模块,并让它自己在没有在框架中运行任何东西“使其工作”

我仍然搞清楚如何最好地加载依赖的JavaScript文件(可能会使用requrejs或其他依赖加载程序),但我目前还不知道如何“启动”的应用程序,而不需要在框架的AppController

编辑

我创build了一个小型的演示项目来展示手头的问题, 在git-hub上可以看到完整的代码,这个项目做了一些硬编码的事情,当我得到概念是正确的,现在只需要在框架中加载应用程序。 如果可能的话,我可以考虑从哪里获取URL和应用程序名称…

  • 如何在angularjs ui-router中的状态之间共享$ scope数据?
  • AngularJS:指令范围内=&@之间的差异?
  • AngularJS - 获取元素属性值
  • 在AngularJS中使用'范围'从另一个控制器调用一个控制器的方法
  • AngularJS:来自指令的广播事件
  • AngularJS条件ng-disabled不能重新启用
  • 检查对象是否为空,使用ng-show而不是来自控制器?
  • ng-model不适用于AngularJS中的单选button
  • 4 Solutions collect form web for “AngularJS:如何在angular度应用程序中嵌套应用程序”

    您不能在另一个引导模块内引导模块。 引导编译视图并将一个rootScope绑定到它,通过DOM遍历它,并设置范围绑定并执行指令链接函数。 如果你这样做了两次,你会遇到问题。

    你可能不得不重新考虑你的架构。 我认为,与Angular有关的“模块”或“应用程序”这个词是错误的,会把你引向错误的道路。

    应用程序中的每个“用户安装的应用程序”应该可能真的由您的应用程序模块中的控制器控制,或注册到您的应用程序模块引用的模块。 所以你不会“启动多个应用程序”,你只需要启动一个,引用其他模块,然后使用这些模块中的控制器来控制屏幕上的部分视图。

    你要做的是当一个新的“小部件”被安装,你注册它的模块文件(.js)与系统,其中将包含一个名为WidgetCtrl的控制器,然后当你的页面加载,你会引用的部件模块上的应用程序模块。 从那里它应该可用于dynamic分配元素使用ng-controller和/或ng-include。

    我希望这是有道理的。

    与目前接受的答案相反,实际上是可以的。

    我正在研究类似的问题,并build议我的答案是不能接受的。 我以前写过多个应用程序的页面,但是几年前,应用程序相互独立。 基本上有两件事情要做:

    • 告诉主应用程序忽略一个子元素。
    • 引导子元素。

    有一个ng-non-bindable属性,它告诉AngularJS忽略这个元素。 这处理我们的第一个问题。

    但是,当您尝试引导子元素时, AngularJS会抛出一个错误,告诉你它已经被引导(至less对我来说,版本1.2.13)。 下面的诀窍可以做到

     <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> 

    这个解决scheme并不完美。 理想情况下,ng-non-bindable属性可以将所需的data-$ injector属性添加到元素。 我将做一个function,并希望对AngularJS提出一个请求。


    我没有机会提出要求。 显然,我应该说,一些内部已经改变,但ng-non-bindable仍然在版本1.3.13使用Ventzy Kunev的演示代码(再次感谢,请参阅下面的链接)。

    以及如果每个子应用程序在自己的模块中,您可以使用angular.bootstrapdynamic加载该模块。 当一个特定的应用程序的URL加载,你可以获取必要的脚本,然后当承诺解决,你可以做的东西沿线:

     // 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']); 

    希望这可以帮助

    类似于上面的UnicodeSnowman的答案,另一个可能的解决scheme似乎是为我的需要工作(我在文档站点上构build了一个活动的Angular编辑器)是通过使用独立的<div id="demos">来手动处理引导过程从主<div id="myApp">

    这篇文章是非常有用的,让它正常工作。

    一般过程

    • 创build你的主应用程序(我select手动引导,但你可能能够使用ng-app这个部分)
    • 创build一个新的HTML结构/应用程序(在我的情况下,演示应用程序):
    • 将其附加到带有自定义ID的演示版div: someCoolDemoContainer
    • Boostrap新创build的应用程序
    • 将其移回原始应用程序(用于布局/定位目的)

    代码示例 (未经testing;仅显示基本过程)

     <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>