[译] 如何手动启动 Angular 程序
原文链接: How to manually bootstrap an Angular application Angular 官方文档写到,为了启动 Angular 程序,必须在 platformBrowserDynamic().bootstrapModule(AppModule); 这行代码 the entry point for Angular on a web page. Each page has exactly one platform,and services (such as reflection) which are common to every Angular application running on the page are bound in its scope. 同时,Angular 也有 运行的程序实例(running application instance)的概念,你可以使用 当 @NgModule({ imports: [BrowserModule],declarations: [AppComponent],bootstrap: [AppComponent] }) export class AppModule {}
Angular 启动过程隐含了你想要哪一个组件去启动程序,但是如果启动程序的组件是在运行时才被定义的该怎么办呢?当你获得该组件时,又该如何启动程序呢?事实上这是个非常简单的过程。 NgDoBootstrap假设我们有 import { Component } from '@angular/core'; @Component({ selector: 'a-comp',template: `<span>I am A component</span>` }) export class AComponent {} @Component({ selector: 'b-comp',template: `<span>I am B component</span>` }) export class BComponent {} 然后在 @NgModule({ imports: [BrowserModule],declarations: [AComponent,BComponent],entryComponents: [AComponent,BComponent] }) export class AppModule {} 注意,这里因为我们得自定义启动程序,从而没有在 由于我们不知道 <body> <h1 id="status"> Loading AppComponent content here ... </h1> </body> 如果此时运行程序会有如下错误: The module AppModule was bootstrapped,but it does not declare “@NgModule.bootstrap” components nor a “ngDoBootstrap” method. Please define one of these 错误信息告诉我们, Angular 在向抱怨我们没有指定具体使用哪一个组件来启动程序,但是我们的确不能提前知道(译者注:我们不知道服务端何时返回什么)。等会儿我们得手动在 export class AppModule { ngDoBootstrap(app) { } } Angular 会把 让我们写一个自定义方法 // app - reference to the running application (ApplicationRef) // name - name (selector) of the component to bootstrap function bootstrapRootComponent(app,name) { // define the possible bootstrap components // with their selectors (html host elements) // (译者注:定义从服务端可能返回的启动组件数组) const options = { 'a-comp': AComponent,'b-comp': BComponent }; // obtain reference to the DOM element that shows status // and change the status to `Loaded` //(译者注:改变 id 为 #status 的内容) const statusElement = document.querySelector('#status'); statusElement.textContent = 'Loaded'; // create DOM element for the component being bootstrapped // and add it to the DOM // (译者注:创建一个 DOM 元素) const componentElement = document.createElement(name); document.body.appendChild(componentElement); // bootstrap the application with the selected component const component = options[name]; app.bootstrap(component); // (译者注:使用 bootstrap() 方法启动组件) } 传入该方法的参数是 先构建一个 function fetch(url) { return new Promise((resolve) => { setTimeout(() => { resolve('b-comp'); },2000); }); } 现在我们拥有 export class AppModule { ngDoBootstrap(app) { fetch('url/to/fetch/component/name') .then((name)=>{ this.bootstrapRootComponent(app,name)}); } } 这里我做了个 stackblitz demo 来验证该解决方法。(译者注:译者把该作者 demo 中 angular 版本升级到最新版本 5.2.9,可以查看 angular-bootstrap-process,2 秒后会根据服务端返回信息自定义启动 在 AOT 中能工作么?当然可以,你仅仅需要预编译所有组件,并使用组件的工厂类来启动程序: import {AComponentNgFactory,BComponentNgFactory} from './components.ngfactory.ts'; @NgModule({ imports: [BrowserModule],BComponent] }) export class AppModule { ngDoBootstrap(app) { fetch('url/to/fetch/component/name') .then((name) => {this.bootstrapRootComponent(app,name);}); } bootstrapRootComponent(app,name) { const options = { 'a-comp': AComponentNgFactory,'b-comp': BComponentNgFactory }; ... 记住我们不需要在 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |