專家解讀:利用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服務應該在底層框架升級後,儘快適應到新的底層框架體系中,提升服務的可用性和穩定性。


點擊關注,第一時間瞭解華爲雲新鮮技術~

相關文章
相關標籤/搜索