Angular 2中的多个模块

6
我有一个Angular 2应用程序(RC7),最初只是一个组件,但现在正在项目中以各种不同的方式使用(有时完全无关)。
因此,使用单个 NgModule 引导所有组件似乎是一个非常糟糕的想法,这会导致很多冗余代码。我正在努力找到一种方法来拥有多个模块(Module A将包含Component A,Module B将具有Component B等),并仍然允许在单个页面上引导多个A2应用程序。
实际上,我想要实现的是:
第1页引导Module A - 可以工作
第2页引导Module B - 可以工作
第3页引导Module A和Module B - 无法工作index.html
<script src="/angular2/node_modules/zone.js/dist/zone.js"></script>
<script src="/angular2/node_modules/reflect-metadata/Reflect.js"></script>
<script src="/angular2/node_modules/systemjs/dist/system.src.js"></script>
<script src="/angular2/systemjs.config.js"></script>


<script type="text/javascript">
    System.import('appOne').catch(function(err){ console.error(err); });
    System.import('appTwo').catch(function(err){ console.error(err); });
</script>

systemjs.config.js

(function (global) {
    System.config({
        paths: {
            'npm:': '/angular2/node_modules/'
        },
        map: {
            appOne: '/angular2/',
            appTwo: '/angular2/',
        },
        packages: {
            appOne: {
                main: './appOne.main.js',
                defaultExtension: 'js'
            },
            appTwo: {
                main: './appTwo.main.js',
                defaultExtension: 'js'
            },
        }
    });
})(this);

AppOne和AppTwo的模块只是简单地引导相关组件(componentOne和componentTwo)。但是,两者不会同时在同一页上呈现。我在控制台中没有错误,但无论在systemjs.config.js文件中列出的哪个包都是唯一加载的。

有人能看出为什么它可能不起作用吗? 或者也许可以推荐另一种组织我的模块的方式。 我不想有一个包含所有组件、服务等的父模块——这似乎违背了Angular 2嵌套组件树的初衷,并最终指数级影响页面加载时间。

提前致谢。

3个回答

5
您可以从AppModule启动一系列组件数组,例如以下内容:
import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import {AppComponent} from "./app.component";
import {MainSidebarComponent} from "./menus/main-sidebar.component";
import {FormsModule} from "@angular/forms";
import {appRouting} from "./app.routes";
import {DashBoardComponent} from "./dashboard/dashboard.component";
import {HomeComponent} from "./home/home.component";
import {LoginComponent} from "./login/login.component";
import {UsersModule} from "./users/users.module";
import {TopBarComponent} from "./menus/top-bar.component";

@NgModule({
    imports:      [
        BrowserModule,
        FormsModule,
        appRouting,

        UsersModule
    ],
    declarations: [
        AppComponent,
        MainSidebarComponent,
        TopBarComponent,
        DashBoardComponent,
        HomeComponent,
        LoginComponent
    ],
    bootstrap:    [ AppComponent, MainSidebarComponent, TopBarComponent ]
})
export class AppModule { }

然后在你的index.html文件中

<!doctype html>
<head>
    <base href="/">
    <meta charset="UTF-8">

    <!-- 1. Load libraries -->
    <!-- Polyfill(s) for older browsers -->
    <script src="node_modules/core-js/client/shim.min.js"></script>
    <script src="node_modules/zone.js/dist/zone.js"></script>
    <script src="node_modules/reflect-metadata/Reflect.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    <!-- 2. Configure SystemJS -->
    <script src="systemjs.config.js"></script>
    <script>
        System.import('app').catch(function (err) {
            console.error(err);
        });
    </script>
</head>
<body class=" sidebar_main_open sidebar_main_swipe">

<header id="header_main">
 <top-bar></top-bar>
</header><


<aside id="sidebar_main">
    <main-sidebar></main-sidebar>
</aside>


<div id="page_content">
    <div id="page_content_inner">
        <my-app>Loading....</my-app>
    </div>
</div>
</body>
</html>

@jcmodan:如何在Angular4中实现这个功能? - J.K.A.

4

如果有人感兴趣,这个问题是由于引导引起的。必须同时引导两个应用程序才能使它们正常工作。

index.html

<script src="/angular2/node_modules/zone.js/dist/zone.js"></script>
<script src="/angular2/node_modules/reflect-metadata/Reflect.js"></script>
<script src="/angular2/node_modules/systemjs/dist/system.src.js"></script>
<script src="/angular2/systemjs.config.js"></script>


<script type="text/javascript">
    System.import('appOneAndTwo').catch(function(err){ console.error(err); });
</script>

systemjs.config.js

(function (global) {
    System.config({
        paths: {
            'npm:': '/angular2/node_modules/'
        },
        map: {
            appOne: '/angular2/',
            appTwo: '/angular2/',
            appOneAndTwo: '/angular2/',
        },
        packages: {
            appOne: {
                main: './appOne.main.js',
                defaultExtension: 'js'
            },
            appTwo: {
                main: './appTwo.main.js',
                defaultExtension: 'js'
            },
            appOneAndTwo: {
                main: './appOneAndTwo.main.js',
                defaultExtension: 'js'
            },
        }
    });
})(this);

appOneAndTwo.main.ts

import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {AppOneModule} from './app/app.one.module';
import {AppTwoModule} from './app/app.two.module';

platformBrowserDynamic().bootstrapModule(CommentAppModule);
platformBrowserDynamic().bootstrapModule(WorkflowAppModule);

这仍然不是理想的,因为我必须为我创建的每个Angular 2应用程序组合创建一个新的main.ts文件,但这意味着只有在必要时才会严格导入导入的内容,并且有效负载不会对最终用户产生影响。
我目前正在研究AoT编译器(https://angular.io/docs/ts/latest/cookbook/aot-compiler.html)和使用Webpack进行代码混淆/压缩以进一步减小有效负载大小。

https://www.tutorialspoint.com/angular2/angular2_modules.htm 也非常有助于理解 SystemJS 和 Angular 2 模块。 - RyanGled
当你运行ng build --prod时,你是如何在生产环境中处理这个问题的?它会在最后一个代码示例中创建问题:https://stackoverflow.com/questions/52892251/bootstrap-multiple-or-single-modules-based-on-url-in-main-ts - CularBytes
@CularBytes 这是两年前的事情了,早在 Angular CLI 为您处理所有 AoT 复杂性之前。现在它肯定已经过时了。 - RyanGled

0
我不确定您是否能够达到您想要的精确解决方案,但您可以尝试懒加载一些模块。
例如,您可以创建一个AppModule(用于引导)。在AppModule中,您只导入“home”模块(我将其称为HomeModule)。
然后,所有其他模块都可以进行懒加载(reference)。

我不确定我是否理解正确,但我没有使用路由,只是在同一个视图中同时使用静态选择器。当systemJS单独调用<appOne>和<appTwo>时,两者都能正常工作,但不幸的是它们无法一起加载;可能是systemJS配置问题或Angular2 DI问题? - RyanGled

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接