Angular技巧汇总

一、声明全局的类型定义

    声明项目的全局类型,同时不需要在各个Ts文件中import {XXX} from 'xxx'  ,就能直接引用!方法是:

     增加src/typings.d.ts文件 ,在文件中增加  interface IName {  name:string ; } 的类型定义。

     那么IName这个类型在所有的TS文件中自动可以访问 ! 

    注意:不要在代码前增加  export 的关键字。   

    参考: 3rd Party Lib

二、在懒加载指定模块前,动态加载一个js文件。

     通常我们在项目中引用第三方包,一种是import 方法,其代码最终是打包一起;一种是配置angular.json文件,其中有scripts : [] ,在里面增加相应的js完整路径达到引用js文件, 其代码不参与构建,会在首页加载时,做为普通的外挂脚本文件引入。

     无论是打包在一起,还是外挂脚本,都是会增加初始加载的负担!比如echarts.js 有800kb的大小,在初始的登录页面,用户根本用不到图表的功能,甚至进入主界面的模块后,也不需要加载它, 当仅我在点击到某些有图表页面的页面时,才必须加载echarts.js文件。我们的项目代码通常会拆分成多个“功能模块”,每个模块负责一组功能相近的页面,这些模块可以懒加载,就是当路由到相关页面时,才去加载模块。

     那么如何实现,在懒加载模块时,动态的引入一个依赖js文件?

这里用到两个技术:

   1、解析路由守卫,参考官方文档,   路由守卫有三种:

  •      激活守卫_CanActivate_ :  在函数返回true时,才能进入路由页面。
  •      离开守卫_CanDeactivate_ :  在函数返回true时,才能离开路由页面。
  •      解析守卫Resolve          :   在函数返回的Promise对象成功后,才进入路由页面。

  2、动态插入js脚本。

    先new  Promise() 后,创建一个<script>的dom元素指向动态加载的js文件,并监听它的onload事件,然后把它插入到页面的头部。当加载成功后,让Promise对象resolve即可。

    完整的代码:

先定义一个PreloadScriptResolver服务:

1@Injectable({ 2 providedIn: 'root' 3}) 4export class PreloadScriptResolver implements Resolve<IPreloadScriptResult[]> { 5 // 1、全局可动态插入的js列表。 6 private scripts: any = { 7 echarts: { loaded: false, src: "assets/lib/echarts.min.js" }, 8 canvasGauges: { loaded: false, src: "assets/lib/gauge.min.js" }, 9 sockjs: { loaded: false, src: "assets/lib/sockjs.min.js" } 10 }; 11 load(...scripts: string[]) { 12 const promises = scripts.map(script => this.loadScript(script)); 13 return Promise.all(promises); 14 } 15 loadScript(name: string): Promise<IPreloadScriptResult> { 16 return new Promise((resolve, reject) => { 17 if (this.scripts[name].loaded) { // 防止多次加载 18 resolve({ script: name, loaded: true, status: 'Already Loaded' }); 19 } else { 20 // 2、动态插入js文件 21 const script = document.createElement('script'); 22 script.type = 'text/javascript'; 23 script.src = this.scripts[name].src; 24 script.onload = () => { 25 this.scripts[name].loaded = true; 26 resolve({ script: name, loaded: true, status: 'Loaded' }); 27 }; 28 script.onerror = (error: any) => reject({ script: name, loaded: false, status: 'Loaded Error:' + error.toString() }); 29 document.head.appendChild(script); 30 } 31 }); 32 } 33 // 3、解析守卫从当前路由的data.preloadScripts中取到依赖的js列表,并加载它们 34 resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<IPreloadScriptResult[]> { 35 return this.load(...route.routeConfig.data.preloadScripts); 36 } 37}

去相应模块的路由定义文件中:

1const routes: Routes = [ 2 { 3 path: "", 4 component: DashboardComponent, 5 resolve: { 6 preloadScripts: PreloadScriptResolver 7 }, 8 data: { 9 preloadScripts: ["echarts", "canvasGauges", "sockjs"] // 5、传入当前路由依赖的js列表 10 }, 11 children: [ 12 { 13 path: "widgets", 14 。。。。。。 15 16 17 }

三、http请求返回200,响应体是一个空格时,报错。

在Angular中,使用HttpClient请求时, 如果this.http.get("url"}后,响应结果不走成功,直接进入error,但是控制台中的网络中,显示状态码是200, 且控制台打印报告“Unexpected end of JSON input” ,就是这种情况了。

此时需要增加一个参数:this.http.get( url  , {responseType: 'text'});

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

Angular技巧汇总 - HelloWorld