专家解读:利用Angular项目与数据库融合实例

摘要:面对如何在现有的低版本的框架服务上,运行新版本的前端服务问题,华为云前端推出了一种融合方案,该方案能让独立的Angular项目总体运行在低版本的框架服务上,经过各类适配手段,让Angular项目也能获取到外层框架服务的资源。

华为云前端服务前期采用AngularJs做为框架技术栈,技术较为老旧,性能较差,在华为云快速发展的今天,显然不能知足要求。所以咱们必需要升级前端技术栈,使用Angular2+来承载咱们的前端服务。GeminiDB做为新服务,也是数据库乃至华为云将来的重点服务,做为前端部分,必须在技术上使用最前沿的框架,以最大地提升用户体验。javascript

可是技术栈的升级不是一蹴而就的,尤为是在华为云,全部的云服务必须在框架服务的底座上运行,而框架服务承载了全部的云服务,若是要进行技术栈升级,必然是一个缓慢的过程。GeminiDB做为华为云服务里的一员,也不可能脱离框架服务而存在。所以存在一个问题,就是如何在现有的低版本的框架服务上,运行新版本的前端服务。css

为了解决以上问题,华为云前端推出了一种融合方案,该方案能让独立的Angular项目总体运行在低版本的框架服务上,经过各类适配手段,让Angular项目也能获取到外层框架服务的资源。html

底层项目

底层项目使用webpack打包,打包后经过在index.html里引入businessAll.js文件,以该文件为入口启动整个框架服务。前端

<script type="text/javascript" src="businessAll.js"></script>复制代码

在底层框架服务启动后,再渲染出具体云服务内容。java

<div class="service-content-view" ui-view ng-animate="{enter:'fade-enter'}"></div>复制代码

Angular项目

Angular项目支持独立运行,有单独的index.html,也有单独的main.ts入口。可是若是但愿Angular项目运行在底层框架服务上,就必须把Angular项目看做是一个独立的模块,把项目总体引入到底层项目中。所以,咱们能够预先把Angular项目编译好,放到底层项目的一个目录下。在运行底层项目时,在index.html里将Angular项目引进来,独立运行。webpack

<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项目均能独立,可是要让二者融合起来,会遇到如下几个问题:web

1.底层项目中如何渲染出Angular项目。数据库

2.Angular项目依赖底层项目的资源,如何保证Angular项目在底层项目运行起来后再运行。bootstrap

3.如何解决底层项目和Angular项目的路由冲突问题。bash

渲染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项目来讲,要使用底层框架服务提供的内容,首先要求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服务应该在底层框架升级后,尽快适应到新的底层框架体系中,提升服务的可用性和稳定性。


点击关注,第一时间了解华为云新鲜技术~

相关文章
相关标签/搜索