Angular技巧彙總

1、聲明全局的類型定義

    聲明項目的全局類型,同時不須要在各個Ts文件中import {XXX} from 'xxx'  ,就能直接引用!方法是:javascript

     增長src/typings.d.ts文件 ,在文件中增長  interface IName {  name:string ; } 的類型定義。java

     那麼IName這個類型在全部的TS文件中自動能夠訪問 ! git

    注意:不要在代碼前增長  export 的關鍵字。   github

    參考: 3rd Party Libjson

2、在懶加載指定模塊前,動態加載一個js文件。

     一般咱們在項目中引用第三方包,一種是import 方法,其代碼最終是打包一塊兒;一種是配置angular.json文件,其中有scripts : [] ,在裏面增長相應的js完整路徑達到引用js文件, 其代碼不參與構建,會在首頁加載時,作爲普通的外掛腳本文件引入。canvas

     不管是打包在一塊兒,仍是外掛腳本,都是會增長初始加載的負擔!好比echarts.js 有800kb的大小,在初始的登陸頁面,用戶根本用不到圖表的功能,甚至進入主界面的模塊後,也不須要加載它, 當僅我在點擊到某些有圖表頁面的頁面時,才必須加載echarts.js文件。咱們的項目代碼一般會拆分紅多個「功能模塊」,每一個模塊負責一組功能相近的頁面,這些模塊能夠懶加載,就是當路由到相關頁面時,纔去加載模塊。promise

     那麼如何實現,在懶加載模塊時,動態的引入一個依賴js文件?網絡

    這裏用到兩個技術:app

   一、解析路由守衛,參考官方文檔,   路由守衛有三種:echarts

  •      激活守衛CanActivate     :  在函數返回true時,才能進入路由頁面。
  •      離開守衛CanDeactivate :  在函數返回true時,才能離開路由頁面。
  •      解析守衛Resolve          :   在函數返回的Promise對象成功後,才進入路由頁面。

  二、動態插入js腳本。

    先new  Promise() 後,建立一個<script>的dom元素指向動態加載的js文件,並監聽它的onload事件,而後把它插入到頁面的頭部。當加載成功後,讓Promise對象resolve便可。

    完整的代碼:

先定義一個PreloadScriptResolver服務:

@Injectable({
  providedIn: 'root'
})
export class PreloadScriptResolver implements Resolve<IPreloadScriptResult[]> {
  // 一、全局可動態插入的js列表。
  private scripts: any = {
    echarts: { loaded: false, src: "assets/lib/echarts.min.js" },
    canvasGauges: { loaded: false, src: "assets/lib/gauge.min.js" },
    sockjs: { loaded: false, src: "assets/lib/sockjs.min.js" }
  };
  load(...scripts: string[]) {
    const promises = scripts.map(script => this.loadScript(script));
    return Promise.all(promises);
  }
  loadScript(name: string): Promise<IPreloadScriptResult> {
    return new Promise((resolve, reject) => {
      if (this.scripts[name].loaded) {     // 防止屢次加載
        resolve({ script: name, loaded: true, status: 'Already Loaded' });
      } else {
        // 二、動態插入js文件
        const script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = this.scripts[name].src;
        script.onload = () => {
          this.scripts[name].loaded = true;
          resolve({ script: name, loaded: true, status: 'Loaded' });
        };
        script.onerror = (error: any) => reject({ script: name, loaded: false, status: 'Loaded Error:' + error.toString() });
        document.head.appendChild(script);
      }
    });
  }
  // 三、解析守衛從當前路由的data.preloadScripts中取到依賴的js列表,並加載它們
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<IPreloadScriptResult[]> {
    return this.load(...route.routeConfig.data.preloadScripts);
  }
}

去相應模塊的路由定義文件中:

const routes: Routes = [
  {
    path: "",
    component: DashboardComponent,
    resolve: {
      preloadScripts: PreloadScriptResolver  
    },
    data: {
      preloadScripts: ["echarts", "canvasGauges", "sockjs"]  // 五、傳入當前路由依賴的js列表
    },
    children: [
      {  
        path: "widgets",
    。。。。。。


   }

3、http請求返回200,響應體是一個空格時,報錯。

在Angular中,使用HttpClient請求時, 若是this.http.get("url"}後,響應結果不走成功,直接進入error,可是控制檯中的網絡中,顯示狀態碼是200, 且控制檯打印報告「Unexpected end of JSON input」 ,就是這種狀況了。

此時須要增長一個參數:this.http.get( url  , {responseType: 'text'});  

相關文章
相關標籤/搜索