Angular中集成Script脚本你还不会?看这篇就够了

背景:

     最近在做angular项目时,需要集成一个控件,其中需要引入最新的js文件,所以我们要使用:

 

像这样的方式,并需要写一些初始化的逻辑显示此控件。

先看看效果:

 

分析:Angular中集成Script脚本你还不会?看这篇就够了_第1张图片

angular中使用的是ts语言(es6+),html里也舍去了script脚本。那到底html和script有什么关系呢?

  • 首先,在Angular2框架之中实际使用的是ES6,全称ECMAScript6,是Javascript的下一个版本。官方的例子则是基本采用TS,全称TypeScript,是JS的一个超集。
  • 为什么采用新的语言,而不是沿用当前的ES5,官网和社区已经有了很多解释了,新语言当然有新语言的优势,比如定义变量,可以指定类型,而在程序中用错类型,则会在编译过程中就给出警告,不至于等到上线了才发现BUG。
  • 既然采用了新的语言,为了跟当前的浏览器系统兼容,当然就有一个翻译过程,准确的说,甭管是TS还是ES6,甚至将来可能的ES7,在当下,都要翻译成ES5,才能在当前流行的浏览器之中运行。这个翻译,行话上讲,也就是“编译”。
  • 事实上,编译不仅仅干这么一点事,很多的优化工作、查错工作,也是在这个阶段完成的,比如你使用了没有定义的变量、函数;比如你用错了函数类型;比如你使用了某个函数库但只是用了其中一小部分,那么多没用的部分应当排除掉避免占用宝贵的下载带宽,这些都是在编译过程做到的。
  • 好了,既然经过了这么复杂的动作,这个编译也必不可少,那么实际上答案已经出来了:那就是,很多原有理所应当存在的东西,就比如你在HTML中定义的JS对象、变量、函数,那些都是在执行环节,浏览器中才存在的。而在编译阶段,那些东西还只是停留在字符状态,Angular当然并不知道他们存在,也就无法直接的、像原来我们使用HTML-JS一样来使用它们了,这就如同上面那张图,看上去海天一色,互相映衬,但在根本上,它们是在两个世界。

解释:

你肯定早看到了,大量的第三方模块和代码库,通过NPM的管理,共存于这个架构中,彼此友好的相处。你原有的工作,完全可以用同样的方式来工作。
你也可能会说,可我有很多代码没有做到那么好的面向对象化包装,也不想做那么复杂,该怎么办呢?AngularJS也提供了至少2个方法,来完成两个世界的打通工作。

代码实现:

1.通过declare方式引入

在最外层的index.html中嵌入:




  
  Demo
  
  
  
  
  
  
  
  


  


    var test = 'test'

  是我嵌入的一脚本,并且设置了一个变量

在ts代码里直接定义 :

import { Component, OnChanges, OnInit, OnDestroy, ViewChild, AfterViewInit, AfterViewChecked, ViewContainerRef, ComponentFactoryResolver } from '@angular/core';
declare let test: string;
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.less']
})
export class AppComponent implements OnInit {
  constructor() {
    // webGlObject.init();
    // console.log(window)
    // console.log(test)
  }
  ngOnInit(): void {
    console.log(test)

如上,AppComponent 不会去管理test,在编译或者运行时,会去script里寻找test,如果没有则打印undfiend。相当于ts代码和script完全是独立的两部分,只是在运行时候才会有关联

2.通过window方式引入(不推荐,angular也许不再浏览器执行)

import { Component, OnChanges, OnInit, OnDestroy, ViewChild, AfterViewInit, AfterViewChecked, ViewContainerRef, ComponentFactoryResolver } from '@angular/core';
declare let test: string;
declare let window: any;
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.less']
})
export class AppComponent implements OnInit {
  constructor() {
    // webGlObject.init();
    // console.log(window)
    // console.log(test)
  }
  ngOnInit(): void {
    console.log(window.test)

这种方式也会输出test的值。

思考:既然直接能访问到window对象,那很多属性都能直接用吧?

如果将来这段Angular代码,很可能不是运行在一个浏览器,其中可能根本没有window/document对象,那时候,这段代码就出错了。当然你可能会说,不不不,我就是在浏览器运行,不考虑别的。OK,我也不较劲,你当我没说,你完全可以就这么用。
但是比较规范的办法,应当是把window对象以及你需要的其它类似对象,写成一个服务,然后注入到app.component之中,这样,即便将来运行环境有变化,只修改服务部分代码,你的主程序完全可以不用修改。

 

 

你可能感兴趣的:(Angular使用)