根据main.ts中的URL引导多个或单个模块 [英] Bootstrap multiple or single modules based on URL in main.ts

查看:169
本文介绍了根据main.ts中的URL引导多个或单个模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个无法完全转移到完整角度项目的(.NET Framework MVC)Web项目,因此我无法使用angular的路由进行延迟加载,但是我也不想加载所有包含角度的内容使用组件.这是一种企业解决方案,很难说(便宜"):嘿,让我们充分利用有角度的东西,而无需考虑旧项目!".

I am working with a (.NET Framework MVC) web project that cannot be fully transferred to a full angular project, so I cannot use angular's routing to lazy load, but I also don't want to load everything where the angular components are used. It is an enterprise solution where it is not easy (and cheap) to say: "Hey, lets fully utilize angular and forget about the old project!".

我认为,我已经以一种干净的方式解决了这个问题,可以根据URL加载不同的模块,从而避免将所有内容一起加载:

So I have solved this, in my opinion, in a clean way to load different modules based on URL, to avoid loading everything all together:

main.ts

console.log("bootstrapping start");
if (window.location.pathname.toLowerCase().includes("contactplans/details")) {
    console.log("bootstrapping contactplan details");
    platformBrowserDynamic().bootstrapModule(ContactplanDetailsModule)
        .catch(err => console.log(err));
} else if (window.location.pathname.toLowerCase().includes("contactplans/index") || window.location.pathname.toLowerCase().endsWith("contactplans") || window.location.pathname.toLowerCase().includes("settings/contactplans")) {
    console.log("bootstrapping contactplan index");
    platformBrowserDynamic().bootstrapModule(ContactplanListModule) //contact plan index and settings page
        .catch(err => console.log(err));
} 
console.log("bootstrap decision done, bootstrapping menu");
platformBrowserDynamic().bootstrapModule(MenuModule)
    .catch(err => console.log(err));

因此,它基于URL加载模块,并在每个页面上加载菜单模块.

So based on the URL, it loads modules and on every page it loads the menu module.

就目前而言,我有点必须这样做,这只是一个小例子,在越来越多的单个页面上,Angular的使用将显着增长,直到我们可以更轻松地切换"到完整页面角度项目(在.NET Core中可以协同工作).

For the time being, I kind-of have to do it this way, this is just a small example the the usage of angular will grow significantly on more and more individual pages until we can more easily 'switch' to a full angular project (within .NET Core which works awesome together).

因此,这在开发上效果很好.使用ng build --watch可以完成所需的操作. 现在进入生产,运行ng build --prod会产生问题.对我来说,它更像是一个 bug ,然后是其他东西.

So, this works fine on development. Using ng build --watch does the desired things. Now going production, running ng build --prod it creates issues. To me it looks more like a bug then something else.

在下面的屏幕截图中,我演示了当我对以上代码进行修改时,在ng build --prod之后产生的结果.

In the below screenshot I demonstrate what is being produced after ng build --prod when I make modifications to above code.

单击此处显示更大的

如您所见,当只使用一行引导程序时,它运行良好,没有错误.

So as you can see, when only using one line of bootstrap, it works fine, no errors.

但是当我有多个想要的东西时,它将实际的Module更改为function() {},这会导致控制台错误:

But when I have multiple like I want to have, it changes the actual Module to function() {} which then gives the console error:

Uncaught Error: No NgModule metadata found for 'function(){}'.

这真的是一个错误还是我做错了什么?

Is this really a bug or am I doing something wrong?

推荐答案

基于url的自举组件

我遇到了同样的问题,我的解决方案是基于url引导不同的组件,而不是引导不同的模块

Bootstrapping component based on url

I had the same problem, my solution was to bootstrap different components based on the url rather than bootstrapping different Modules

该解决方案基于本文:如何手动引导Angular应用程序

The solution is based on this article: How to manually bootstrap an Angular application

您无需编辑main.ts,但是在AppModule中,您可以根据url手动引导不同的组件并将其添加到DOM

You don't edit the main.ts but in the AppModule you bootstrap the different components manually based on the url and add them to the DOM

app.module.ts

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { ContactplanDetailsComponent } from './ContactplanDetails.component';
import { ContactplanListComponent } from './ContactplanList.component';
import { MenuComponent } from './Menu.component';



@NgModule({
  imports: [BrowserModule],
  declarations: [
     ContactplanDetailsComponent,
     ContactplanListComponent,
     MenuComponent
  ],
  //bootstrap: [AppComponent] Bootstrapping is done manually
  entryComponents: [
     ContactplanDetailsComponent,
     ContactplanListComponent,
     MenuComponent
  ]

})
export class AppModule { 
  ngDoBootStrap(app) {
    bootstrapComponent(app);
  }
}

function bootstrapComponent(app) {

  var name = [];

  const options = {
    'contact-plan-details': ContactplanDetailsComponent,
    'contact-plan-list': ContactplanListComponent,
    'menu': MenuComponent
  };

  if (window.location.pathname.toLowerCase().includes("contactplans/details")) {
    name.push("contact-plan-details"); 
  } else if (window.location.pathname.toLowerCase().includes("contactplans/index") || window.location.pathname.toLowerCase().endsWith("contactplans") || window.location.pathname.toLowerCase().includes("settings/contactplans")) {
    name.push("contact-plan-list");
  } 
  name.push("menu")

  name.forEach(function (element) {

    const componentElement = document.createElement(element);
    document.body.appendChild(componentElement);

    const component = options[element];
    app.bootstrap(component);

  });
}

这篇关于根据main.ts中的URL引导多个或单个模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆