【问题标题】:Multiple modules in Angular 2Angular 2 中的多个模块
【发布时间】:2016-10-03 16:15:16
【问题描述】:

我有一个 Angular 2 应用程序 (RC7),它最初是一个单独的组件,但很快在整个项目中以各种不同(有时完全不相关)的方式使用。

因此,单个 NgModule 引导所有组件似乎是一个糟糕的想法,而且会产生大量膨胀。 我正在努力寻找一种方法来拥有多个模块(模块 A 将包含组件 A,模块 B 将包含组件 B 等)并且仍然允许在单个页面上引导多个 A2 应用程序。

在实践中,我想要实现的是:

第 1 页引导模块 A - 可行

第 2 页引导模块 B - 可行

第 3 页引导模块 A 和模块 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 嵌套组件树的要点,并最终会成倍地影响页面加载时间。

提前致谢。

【问题讨论】:

    标签: angular systemjs angular2-modules


    【解决方案1】:

    您可以从 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 中实现这一点
    【解决方案2】:

    对于任何感兴趣的人来说,问题在于引导。两个应用程序必须同时引导才能工作。

    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 进行 uglification/minification 以进一步减少有效负载大小。

    【讨论】:

    【解决方案3】:

    我不知道您是否可以实现您想要的确切解决方案,但您可以尝试延迟加载您的一些模块。

    例如,您创建了一个 AppModule(用于引导)。在 AppModule 中,您只需导入您的“home”模块(我将其称为 HomeModule)。

    比所有其他模块都可以延迟加载 (reference)

    【讨论】:

    • 我不确定我是否理解正确,但我没有使用路由,只是静态选择器在同一个视图中串联工作。 在 systemJS 分别调用它们时都能正常工作,但不幸的是它们不会一起加载;可能是 systemJS 配置问题或 Angular2 DI 问题?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-20
    • 2019-12-11
    • 1970-01-01
    • 1970-01-01
    • 2016-12-24
    • 2018-04-14
    • 1970-01-01
    相关资源
    最近更新 更多