我在一个大型 .Net/AngularJS 应用程序上工作,该应用程序由 20 多个独立的区域(或模块)和一些在所有区域中通用和重用的核心功能组成。
让我详细介绍一下我如何针对我的特定情况执行此操作,它可能会提供一些想法。我使用 .Net 的事实在这里无关紧要,因为这可以通过任何框架实现。
每个区域都充当一个独立的应用程序,仅依赖于始终存在的核心功能。每个区域都有自己的 ASP.Net MVC 路由。每个区域向核心应用程序注册它想要提供的菜单链接。当客户进入应用程序仪表板时,只有应用程序的核心部分。当用户点击菜单中的链接时,它将导航到其中一个区域提供的内容,并且仅加载该区域的核心和资产。
让我们看看这是如何做到的。
在应用程序的主页中,我加载如下脚本:
<script type="text/javascript">
// a JS object with all the necessary app data from the server.
// e.g.: menu data, etc
window.appContext = @Html.Action("ApplicationContext", "Portal"));
</script>
@Scripts.Render("~/bundles/angular-main")
@RenderSection("AngularAreas", required: false)
我使用点 .Net 包和部分。
应用程序的主要(核心)AngularJS 部分由 Angular 配置、国际化服务、全局通知服务、可重用的 UI 组件等组成。加载的是@Scripts.Render("~/bundles/angular-main")
.
当用户导航到该区域时,该@RenderSection("AngularAreas", required: false)
部分将由每个区域填充。
让我们看看一些 AngularJS 代码。这是主要 app.ts 的一部分。
// If user is visiting an Area, the NgModules array will be augmented.
// with the modules the Area wants to provide (to be bootstrapped)
export var LoadNgModules = [
NgModules.Config,
NgModules.Core
];
angular.module(NgModules.Bootstraper, LoadNgModules);
angular.element(document).ready(function () {
angular.bootstrap(document, [NgModules.Bootstraper]);
});
现在让我们看一个示例区域。
这是一个区域如何提供其资产,以输出@RenderSection("AngularAreas", required: false)
:
@section AngularAreas {
@Scripts.Render("~/bundles/areas/staff-management")
}
它是一个简单的包,包含该区域的所有脚本。现在,让我们看看这个区域的 AngularJS 代码的重要部分。
var StaffManagementNgModule = 'areas.staff-management';
// Push our self into the modules to be bootstrapped
LoadNgModules.push(StaffManagementNgModule );
// Define the module
angular
.module(StaffManagementNgModule , ['ngRoute', NgModules.Core])
.config([
'$routeProvider', '$locationProvider', ($routeProvider: ng.route.IRouteProvider, $locationProvider) => {
$routeProvider
.when(staff', { template: '<staff></staff>' })
.when('staff/details/:id', { template: '<staff-details></staff-details>' });
}
]);;
就是这样,从这里开始,Area 就是一个普通的 Angular 应用程序。
总而言之,我们加载主要(核心)AngularJS 功能并提供 LoadNgModules 数组,一个区域可以用它自己的模块填充。
我们将 Area 脚本和“我们的自我”加载到 LoadNgModules 数组中。
最后运行 angular.bootstrap。
为了完整起见,这里是 C# 的片段,展示了一个区域如何向主应用程序指示它是可用的
public class ItemManagementModuleRegistration : IModuleRegistration
{
public void Register(ModuleContext moduleContext)
{
string thisAreaName = "Staff";
moduleContext.RegisterMenu(menuContext =>
{
var ItemsMenu = menuContext.Items(thisAreaName);
// add urls and stuff...
});
// register more stuff with the moduleContext
}
}
使用反射可以很容易地找到“安装”了哪些区域。
这些是设置的主要移动部分。每个区域都可以有自己的 API 和测试。它非常灵活。