【问题标题】:Using Angular 2 components throughout a non-Angular app在整个非 Angular 应用程序中使用 Angular 2 组件
【发布时间】:2017-04-11 20:42:21
【问题描述】:

我有一个预先存在的、成熟的、非 Angular 网络应用程序的分支。我也有一些来自我希望重用的单独应用程序的现有 Angular 2 组件。我想将现有的 Angular 组件分散到各个地方的非 Angular 应用程序中。我想知道这是否可行和可取。请注意,这与Sprinkling Angular 2 components inside a non-angular page 相似但不完全相同。我有一个更具体的场景,我将在下面描述。

目前,我已经弄清楚如何通过引导一个包装了我想要的组件的模块来添加这些 Angular 组件的单个实例。例如。如果我想将 AppComponent 插入到我现有的非 Angular 应用中:

app.module.ts:

@NgModule({
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.ts:

@Component({
  selector: 'my-app'
  template: '<span>{{value}}</span>'
  ...
})
export class AppComponent { 
   public value: string;
   ...
 }

每当我想要一个 AppComponent 时,我只需附加一个 my-app 元素并按如下方式引导模块:

platformBrowserDynamic().bootstrapModule(AppModule);

这工作得非常好,并给出了我想要的确切结果对于 AppComponent 的单个实例。但是,我的用例要求我在 DOM 的不同位置有 两个同时的 AppComponent 实例。如果我再次尝试引导 AppModule,核心 Angular 代码会将第二个 AppModule 附加到首先出现在 DOM 中的my-app 元素,从而有效地擦除我的第一个 AppModule 实例。有没有办法告诉 Angular 要附加到哪个 my-app 元素?或者有什么办法解决这个问题?

HTML 示例

假设我将&lt;my-app&gt; 附加到&lt;body&gt;。然后我的 HTML 看起来像:

<body>
  <my-app>
  </my-app>
</body>

接下来,如果我调用 platformBrowserDynamic().bootstrapModule(AppModule); 并在 AppComponent 的任何位置设置 value = '111',我的 HTML 如下所示:

<body>
  <my-app>
    <span>111</span>
  </my-app>
</body>

然后我在 HTML 中添加另一个 my-app 选择器,所以它看起来像:

<body>
  <my-app>
    <span>111</span>
  </my-app>
  <my-app>
  </my-app>
</body>

然后,如果我调用 platformBrowserDynamic().bootstrapModule(AppModule); 并在新创建的 AppComponenet 中的 AppComponent 逻辑中的任何位置设置 value = '222',我的 HTML 看起来像:

<body>
  <my-app>
    <span>222</span>
  </my-app>
  <my-app>
  </my-app>
</body>

当我想要的结果是:

<body>
  <my-app>
    <span>111</span>
  </my-app>
  <my-app>
    <span>222</span>
  </my-app>
</body>

总结:在整个非 Angular 应用程序中使用 Angular 组件是否可行且可取?是否可以同时拥有同一个 Angular 模块的 2 个可见实例?

谢谢!

【问题讨论】:

  • 你能添加一些 html 来说明你的问题吗?很快就有可能
  • @yurzui 我刚刚用一个 HTML 示例更新了 OP。如果还不清楚,请告诉我。
  • 你能举一些例子来说明你如何设法将角度组件添加到非角度应用程序中吗?请

标签: angular typescript


【解决方案1】:

根据您的情况,我将编写以下代码:

let bootstrapComponentFn: (node: HTMLElement) => void;

platformBrowserDynamic().bootstrapModule(AppModule).then((moduleRef: 

  NgModuleRef<AppModule) => {
    const appRef = moduleRef.injector.get(ApplicationRef);
    const zone: NgZone = moduleRef.injector.get(NgZone);
    const rootComponentFactory = (moduleRef as any).bootstrapFactories[0];  

    bootstrapComponentFn = (node) => {
      zone.run(() => {
        const compRef = rootComponentFactory.create(Injector.NULL, [], node);
       appRef.attachView(compRef.hostView);
      })
    }; 
  });
}

一段时间后

setTimeout(function() {
  let node = document.createElement('my-app');
  document.body.appendChild(node);

  bootstrapComponentFn(node);
}, 2000);

另请参阅Plunker Example

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-11
    • 1970-01-01
    • 2017-03-20
    • 2015-07-05
    • 1970-01-01
    • 2017-03-26
    • 1970-01-01
    相关资源
    最近更新 更多