角6 -是否可以在同一页面上使用两个角元组件?

时间:2022-07-23 12:14:45

I'm trying to host independent angular elements that I can drop into a non-angular webpage. It's working great when I have just one.. but when I load two or more on the same page I get this error:

我试图把独立的角元素放到一个非角的网页中。当我只有一个的时候,它工作得很好。但是当我在同一页面上加载两个或更多的文件时,我得到了这个错误:

Uncaught Error: Zone already loaded.

未捕获错误:已加载区域。

I'm using a build script to concatenate my dist files into one js file.. and then dropping that into my project

我正在使用一个构建脚本将我的dist文件连接到一个js文件中。然后把它放到我的项目中

const fs = require('fs-extra')
const concat = require('concat')


const files = [
    './dist/elementsApp/runtime.js',
    './dist/elementsApp/polyfills.js',
    './dist/elementsApp/scripts.js',
    './dist/elementsApp/main.js',
]


fs.ensureDir('elements')
.then(() => {
  console.log('success!')
  concat(files, 'elements/include-me-somewhere-else.js')
})
.catch(err => {
  console.error(err)
})

I can only have one of these js files on one page. I understand angular 7 will make this whole process easier but I'm wondering how I can accomplish this right now.

我只能在一个页面上有一个这样的js文件。我理解角7会使整个过程变得更容易,但我想知道我现在如何能做到这一点。

I've also tried wrapping my exported js file in a self-executing function to try and limit scope.. Doesn't fix anything unfortunately.

我还尝试用自执行函数包装导出的js文件,以尝试限制范围。不解决任何不幸。

Any ideas?

什么好主意吗?

People seem confused about what angular elements are. For clarification you can watch this video https://www.youtube.com/watch?v=4u9_kdkvTsc. the last few mins in particular show an angular element being exported and included on a non angular page. I'm trying to include multiple elements on the same page.

人们似乎对什么是角元素感到困惑。澄清一下,你可以观看这个视频https://www.youtube.com/watch?v=4u9_kdkvTsc。最后的几分钟特别显示了正在导出并包含在非角页面上的角元素。我试图在同一页中包含多个元素。

4 个解决方案

#1


6  

I think you should not use 2 angular on one site.

我认为你不应该在一个点上使用2角。

Solutions can be:

解决方案可以是:

  • Build the whole site in Angular. Other parts of the code can be added to the app.
  • 以角度建造整个场地。代码的其他部分可以添加到应用程序中。
  • Use submodules and merge the two app with a parent router.
  • 使用子模块和合并两个应用与一个父路由器。
  • Use iframe for each Angular component. Then ngzone will not collide.
  • 每个角组件使用iframe。这样ngzone就不会碰撞。

#2


4  

So here's my thoughts based on our earlier discussion. Because each bundle you create with an element is loading in zone.js you're getting error messages:

这是基于我们之前讨论的想法。因为使用元素创建的每个bundle都在区域内加载。你收到错误消息:

Uncaught Error: Zone already loaded.

What you can and should consider is NOT concatinating the './dist/elementsApp/polyfills.js' into your bundle (for each element you bundle you produce). Instead use the polyfill.js file as a separate import into your HTML, and import it before any and all element bundles you're importing.

你所能及应该考虑的,并不是包括“。/dist/elementsApp/polyfill”。把js放入你的包中(对于你产生的每个元素)。而不是使用polyfill。将js文件作为单独的导入导入到HTML中,并在导入任何和所有元素包之前导入它。

#3


1  

Google's Polymer may be what you're looking for instead of angular:

谷歌的聚合物可能是你想要的而不是棱角的:

https://www.polymer-project.org/

https://www.polymer-project.org/

The Polymer library provides a set of features for creating custom elements. These features are designed to make it easier and faster to make custom elements that work like standard DOM elements

聚合物库为创建自定义元素提供了一组特性。这些特性的设计目的是使定制元素像标准DOM元素一样工作更容易、更快

#4


1  

This is a solution that works perfectly on angular 5+. for angular 6 i have not done this. I have done this for a huge CMS project and I inserted components in several pages and even 2 same angular module in one page. You can use one angular project.

这个解在角5+处是完美的。对于角6,我没有这样做。我为一个大型的CMS项目做了这个,我在几个页面中插入组件,甚至在一个页面中插入两个相同的角模块。你可以用一个角度的项目。

in your site, write component tags.

在您的站点中,编写组件标记。

You need to create another module (for example mainHelper) to export each selected angular tags.

您需要创建另一个模块(例如mainHelper)来导出每个选定的角标记。

import {NgModule, ApplicationRef, ComponentFactoryResolver} from '@angular/core';
import {FirstModule} from 'YOUR MODULE PATH';
import {FirstComponent} from 'YOU COMPONENT PATH';
import {SecondModule} from 'YOUR MODULE PATH';
import {SecondComponent} from 'YOU COMPONENT PATH';


@NgModule({
  imports: [
    FirstModule,
    SecondModule
  ],
})

export class MainHelper {
  constructor(private resolver: ComponentFactoryResolver) {
  }
  components = [
FirstComponent,
SecondComponent
  ];


  ngDoBootstrap(ref: ApplicationRef) {
    this.components.forEach((component) => {
      const factory = this.resolver.resolveComponentFactory(component);
      const elements = document.getElementsByTagName(factory.selector); //get angular tags on your main website
      if (elements.length > 0) {
        if (elements.length > 1) {
          const selector = factory.selector;
          for (let i = 0; i < elements.length; i++) {
            elements[i].id = selector + '-' + i;
            (<any>factory).factory.selector = '#' + elements[i].id;
            ref.bootstrap((<any>factory).factory);
            // elements[i].id = '';
          }
          (<any>factory).factory.selector = selector;
        } else {
          ref.bootstrap(component);
        }
      }
    });
  }
}

in your main.ts, you can import MainHelper module and bootstrap the MainHelper.

在你的主。ts,您可以导入主助手模块并引导主助手。

and your FirstModule would be something like this:

你的FirstModule大概是这样的:

import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {BrowserModule} from '@angular/platform-browser'; 
import {FirstComponent} from './first.component';
import {AnotherComponent} from './another/another.component';
@NgModule({
  imports: [
    CommonModule,
    BrowserModule,
  ],
  providers: [
    SampleService // you need provide your services for all the modules
  ],
  declarations: [
    FirstComponent,
    AnotherComponent,
  ],
  bootstrap: [FirstComponent] // important
})
export class ECommerceModule {
}

I hope this helps you.

我希望这对你有帮助。

#1


6  

I think you should not use 2 angular on one site.

我认为你不应该在一个点上使用2角。

Solutions can be:

解决方案可以是:

  • Build the whole site in Angular. Other parts of the code can be added to the app.
  • 以角度建造整个场地。代码的其他部分可以添加到应用程序中。
  • Use submodules and merge the two app with a parent router.
  • 使用子模块和合并两个应用与一个父路由器。
  • Use iframe for each Angular component. Then ngzone will not collide.
  • 每个角组件使用iframe。这样ngzone就不会碰撞。

#2


4  

So here's my thoughts based on our earlier discussion. Because each bundle you create with an element is loading in zone.js you're getting error messages:

这是基于我们之前讨论的想法。因为使用元素创建的每个bundle都在区域内加载。你收到错误消息:

Uncaught Error: Zone already loaded.

What you can and should consider is NOT concatinating the './dist/elementsApp/polyfills.js' into your bundle (for each element you bundle you produce). Instead use the polyfill.js file as a separate import into your HTML, and import it before any and all element bundles you're importing.

你所能及应该考虑的,并不是包括“。/dist/elementsApp/polyfill”。把js放入你的包中(对于你产生的每个元素)。而不是使用polyfill。将js文件作为单独的导入导入到HTML中,并在导入任何和所有元素包之前导入它。

#3


1  

Google's Polymer may be what you're looking for instead of angular:

谷歌的聚合物可能是你想要的而不是棱角的:

https://www.polymer-project.org/

https://www.polymer-project.org/

The Polymer library provides a set of features for creating custom elements. These features are designed to make it easier and faster to make custom elements that work like standard DOM elements

聚合物库为创建自定义元素提供了一组特性。这些特性的设计目的是使定制元素像标准DOM元素一样工作更容易、更快

#4


1  

This is a solution that works perfectly on angular 5+. for angular 6 i have not done this. I have done this for a huge CMS project and I inserted components in several pages and even 2 same angular module in one page. You can use one angular project.

这个解在角5+处是完美的。对于角6,我没有这样做。我为一个大型的CMS项目做了这个,我在几个页面中插入组件,甚至在一个页面中插入两个相同的角模块。你可以用一个角度的项目。

in your site, write component tags.

在您的站点中,编写组件标记。

You need to create another module (for example mainHelper) to export each selected angular tags.

您需要创建另一个模块(例如mainHelper)来导出每个选定的角标记。

import {NgModule, ApplicationRef, ComponentFactoryResolver} from '@angular/core';
import {FirstModule} from 'YOUR MODULE PATH';
import {FirstComponent} from 'YOU COMPONENT PATH';
import {SecondModule} from 'YOUR MODULE PATH';
import {SecondComponent} from 'YOU COMPONENT PATH';


@NgModule({
  imports: [
    FirstModule,
    SecondModule
  ],
})

export class MainHelper {
  constructor(private resolver: ComponentFactoryResolver) {
  }
  components = [
FirstComponent,
SecondComponent
  ];


  ngDoBootstrap(ref: ApplicationRef) {
    this.components.forEach((component) => {
      const factory = this.resolver.resolveComponentFactory(component);
      const elements = document.getElementsByTagName(factory.selector); //get angular tags on your main website
      if (elements.length > 0) {
        if (elements.length > 1) {
          const selector = factory.selector;
          for (let i = 0; i < elements.length; i++) {
            elements[i].id = selector + '-' + i;
            (<any>factory).factory.selector = '#' + elements[i].id;
            ref.bootstrap((<any>factory).factory);
            // elements[i].id = '';
          }
          (<any>factory).factory.selector = selector;
        } else {
          ref.bootstrap(component);
        }
      }
    });
  }
}

in your main.ts, you can import MainHelper module and bootstrap the MainHelper.

在你的主。ts,您可以导入主助手模块并引导主助手。

and your FirstModule would be something like this:

你的FirstModule大概是这样的:

import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common';
import {BrowserModule} from '@angular/platform-browser'; 
import {FirstComponent} from './first.component';
import {AnotherComponent} from './another/another.component';
@NgModule({
  imports: [
    CommonModule,
    BrowserModule,
  ],
  providers: [
    SampleService // you need provide your services for all the modules
  ],
  declarations: [
    FirstComponent,
    AnotherComponent,
  ],
  bootstrap: [FirstComponent] // important
})
export class ECommerceModule {
}

I hope this helps you.

我希望这对你有帮助。