时间:2021-07-01 10:21:17 帮助过:13人阅读
在底层框架服务启动后,再渲染出具体云服务内容。
<div class="service-content-view" ui-view ng-animate="{enter:‘fade-enter‘}"></div>
Angular项目支持独立运行,有单独的index.html,也有单独的main.ts入口。但是如果希望Angular项目运行在底层框架服务上,就必须把Angular项目看作是一个独立的模块,把项目整体引入到底层项目中。因此,我们可以预先把Angular项目编译好,放到底层项目的一个目录下。在运行底层项目时,在index.html里将Angular项目引进来,独立运行。
<link rel="stylesheet" type="text/css" href="{底层项目中Angular项目的路径}/styles.css" /> <script type="text/javascript" src="{底层项目中Angular项目的路径}/runtime.js"></script> <script type="text/javascript" src="{底层项目中Angular项目的路径}/polyfills.js"></script> <script type="text/javascript" src="{底层项目中Angular项目的路径}/main.js"></script>
底层项目和Angular项目均能独立,但是要让两者融合起来,会遇到以下几个问题:
1.底层项目中如何渲染出Angular项目。
2.Angular项目依赖底层项目的资源,如何保证Angular项目在底层项目运行起来后再运行。
3.如何解决底层项目和Angular项目的路由冲突问题。
底层项目分为两部分,一部分是底层框架服务,另一部分是具体云服务。现在我们要做的是把老的云服务项目替换成新的Angular项目,因此我们可以直接在渲染老的云服务的地方替换成新的Angular项目的渲染容器。
<div class="service-content-view" ui-view ng-animate="{enter:‘fade-enter‘}"></div> <app-root></app-root>
底层框架服务对页面渲染上做了一些体验上的优化,因此必须保留原模板中的ui-view,使底层项目正常运行起来,实际上老的云服务项目的渲染内容已经转发到新的Angular项目上面。
底层框架服务给云服务提供了很多公共变量与服务,这些变量和服务是各个云服务必须要使用的,否则云服务将不能正常运作。
对于Angular项目来说,要使用底层框架服务提供的内容,首先要求Angular项目在底层项目运行起来之后再运行。这里采用Augular中的APP_INITIALIZER令牌来解决这个问题。APP_INITIALIZER是一个函数,在程序初始化的时候被调用。这里在根模块的providers中以factory的形式来配置。
import { BrowserModule } from "@angular/platform-browser"; import { NgModule } from "@angular/core"; import { AppInitService } from ‘./services/app-init.service‘; import { AppComponent } from "./app.component"; @NgModule({ declarations: [AppComponent], imports: [BrowserModule], providers: [ AppInitService, { provide: APP_INITIALIZER, useFactory: initializeApp, deps: [AppInitService], multi: true } ], bootstrap: [AppComponent] }) export class AppModule {} export function initializeApp(appInitService: AppInitService) { return (): Promise<any> => { return appInitService.Init(); }; }
在appInitService里,先获取到底层框架的资源,再进行Angular项目的初始化。
import { Injectable } from ‘@angular/core‘; @Injectable() export class AppInitService { constructor() {} Init() { return new Promise<void>((resolve, reject) => { // 获取到底层框架服务的资源 resolve(); }); } }
底层项目使用的是AngularJs,Angular项目获取底层框架服务提供的资源不能通过Angular的方式引入,因此需要借助AngularJS的注入器获取在底层框架中注册的服务组件:
static get(inject: string): any { return (window as any).angular.element(‘html‘).injector().get(inject);} 如,要获取 $rootScope: rootScope = (window as any).angular.element(‘html‘).injector().get(‘$rootScope’);
Angular项目本身有自己的路由,但是Angular项目是运行在底层框架之上的,Angular项目的路由将会被底层框架所拦截。因此,我们也需要在底层框架的项目中配置相同的路由,以免Angular项目中的有效路由被底层框架识导向为404。
Angular项目路由:
{ path: ‘‘, redirectTo: ‘ng2app1‘, pathMatch: ‘full‘ }, { path: ‘ng2app1‘, loadChildren: ‘./ng2app1/ng2app1.module#Ng2app1Module‘, }, { path: ‘ng2app2‘, loadChildren: ‘./ng2app2/ng2app2.module#Ng2app2Module‘, } 底层框架路由: var configArr = [ { name: ‘ng2app1‘, url: ‘/ng2app1‘ }, { name: ‘ng2app2‘, url: ‘/ng2app2‘ } ];
另外,由于底层项目使用的是hash路由,Angular项目中也要做相应的配置,默认是使用的是PathLocationStrategy,需要切换到hash模式。
import { LocationStrategy, HashLocationStrategy } from ‘@angular/common‘; ... providers: [ { provide: LocationStrategy, useClass: HashLocationStrategy } ]
以上方案是在底层框架升级周期长的前提下的一个临时方案,实际上还是存在着不少的问题。比如底层框架对于老的云服务容器是有统一管理的,老的云服务容器会针对不同的场景能够自适应,而融合方案中的Angular项目则不能;每次启动整个项目时,必须要预先编译好里面的Angular项目,再去启动外层的底层框架,开发效率比较低。因此,后续GeminiDB服务应该在底层框架升级后,尽快适应到新的底层框架体系中,提高服务的可用性和稳定性。
点击关注,第一时间了解华为云新鲜技术~
专家解读:利用Angular项目与数据库融合实例
标签:tle initial 时间 location 效率比较 const huawei direct 组件