angular学习笔记

作者: lzb30 | 来源:发表于2018-01-17 22:15 被阅读0次
    angular程序架构

    一、搭建Angular开发环境

    安装nodejs, Angular Cli, WebStorm

    先安装nodejs, 安装完成后用命令来安装Angular Cli
    npm install -g @angular/cli

    使用Angular Cli创建并运行Angular项目

    用ng new 命令来创建一个项目,比如项目名为demo,则输入命令 ng new demo

    分析Angular目录结构及Angular Cli 生成的基础代码

    e2e 端到端的测试目录,用来做自动测试的
    node_modules 第三方的依赖包
    src 源代码目录
    app 包含应用的组件和模块
    assets 用来存放静态资源文件
    environment 环境配置,支持多环境开发,比如开发环境和生产环境可以共用一套代码
    index.html 整个应用的根文件
    main.ts 整个应用的入口点
    polyfills.ts 导入必要的库,使angular可以正常运行在老版本的浏览器
    style.css 应用的全局样式
    test.ts 做自动化测试的
    tsconfig.json ts的配置文件
    .editconfig webStorm的配置文件
    .gitignore git的配置文件
    angular-cli.json angular命令行工具的配置文件
    karma.config.js karma的配置文件,用来执行自动化测试的
    package.json 标准的npm工具的配置文件,当前应用使用的第三方工具包,通过npm i 来安装
    protractor.conf.js 跟karma类似,也是用来做自动化测试
    tslint.json 用来定义ts代码的质量检查

    二、组件

    定义:在angular中组件就是一个ts类,然后通过@Component装饰器装饰,装饰器里面定义了组件的元数据,包括样式,模板等等。

    组件要素

    必备

    装饰器、模板和控制器

    可选

    输入属性@Input---父组件向子组件传递数据
    提供器 providers---用来做依赖注入
    生命周期钩子
    样式表
    动画---angular 提供动画包帮助我们创建组件间的动画效果
    输出属性---用来在组件间共享数据

    模块

    用@NgModule装饰器装饰的一个ts类

    元数据

    declarations 只能声明组件,指令和管道
    imports 引用app模块需要依赖的模块
    providers 用来声明模块中提供什么服务,只能声明服务
    bootstrap 声明模块的主组件

    三、Angular路由

    Routes

    路由配置,保存着哪个URL对应展示哪个组件,以及在哪个RouterOutlet中展示

    RouterOutlet

    在HTML中标记路由内容呈现位置的占位符指令

    Router

    路由的对象,用来跳转路由,在控制器使用

    RouterLink

    在HTML中声明路由导航用的指令,根路由要用‘/’开头,参数是一个数组。.比如 <a [routerLink]="['/']"></a>

    ActivatedRoute

    当前激活的路由对象,保存着路由信息。

    在路由中传递参数的三种方式:

    1、在查询参数中传递
     /product?id=1&name=2     =>      ActivatedRoute.queryParams[id]
    
    2、在路由路径中传递参数
     {path:'product/:id'}     =>     /product/1     =>      ActivatedRoute.params[id]
    
    3、在路由配置中传递参数
     {path:'product', data:[{isProd:true}]}     =>      ActivatedRoute.data[0][isProd]
    

    参数订阅和参数快照snapshot

    如果不会出现组件路由到自身的情况,则可使用参数快照来获取参数。如果会出现路由到自身的情况,则用参数订阅,也就是subcribe()方法。

    为什么要这样做?
    这是因为,当组件路由到自身的时候,由于组件已经被创建,那么就不会再执行ngOninit方法。而通过订阅则可以解决这个问题。

    重定向路由

    在用户访问特定的地址时,将其重定向到其他的地址
    可用redirectTo属性

    子路由

    路由间的父子关系,可以无限嵌套
    在用RouterLink指令时,路由要用'./'开头,表示从当前路由开始

    辅助路由

    路由守卫

    当用户满足某种条件后才允许用户进入或离开路由。

    CanActivate: 处理导航到路由的情况
    CanDeActivate: 处理从当前路由离开的情况
    Resolve: 在路由激活之前获取路由数据

    实现:需要创建一个ts类,该类继承对应的守卫类,实现对应的方法。然后在Routes里面加入对应的属性,再把创建的类添加到providers里面。

    四、依赖注入

    依赖注入解决的问题

    当一个方法或者类依赖其他类时,使用前需要先实例化其他类。当依赖的类多了,要实例化所有的类也是一件麻烦的事。那么能不能把实例化的工作交给其他人做, 我们只需要知道依赖哪些类,而不需要知道具体的实例方法。

    依赖注入DI 和 控制反转IOC

    依赖注入:侧重于描述手段,如何来实现控制反转的手段
    控制反转:侧重于描述目的,即依赖的控制权由代码的内部转移到代码的外部

    使用依赖注入的好处

    1、松耦合、可重用性
    2、提高可测试性

    angular如何实现

    注入器 在构造函数中声明需要用到的类

    constructor(private productService: ProductService){}

    提供器 在模块或组件的providers属性声明provider

    providers:[ProductService]
    providers:[provider:ProductService, useClass: ProductService]
    providers:[provider:ProductService, useClass: AnotherProductService]

    provider指定了提供器的token,跟构造器中声明的类对应。
    useClass指定了具体实例化的类
    providers:[provider:ProductService, useFactory: () => {...}] 工厂提供器
    根据某些条件决定具体实例化哪些对象,也有可能在实例化对象时需要传入参数,这时就需要用到工厂提供器
    在使用工厂方法时,如果需要依赖其他类,则需要用到第三个参数deps:[],在deps的数组中传入需要依赖的类,然后在useFactory的参数中传递进去。
    providers:[provider:"APP_CONFIG", useValue: {isDev:false}]
    useValue可以传值,也可以传对象

    作用域规则

    1、声明在模块时,对所有组件可用
    2、当提供器声明在组件时,只对组件和其子组件可用
    3、当声明在模块和组件具有相同的token时,组件中的提供器会覆盖模块中的提供器
    4、优先将服务提供器声明在组件,只有该提供器对其他组件不可用时才声明在组件中

    注入器的层级关系

    应用级注入器 > 主组件注入器 > 子组件注入器

    五、组件间通讯

    组件的输入输出属性

    输入属性:用@Input()装饰器注解的属性,属性绑定是单项的
    输出属性: 用@Output()装饰器注解的属性 ,需要用到EventEmitter。从angular/core引入

    声明: lastPrice: EventEmitter<PriceQuote> = new EventEmitter();
    可以通过emit(value)方法把值发射出去,父组件就可以通过子组件的事件绑定接收到数据。

    使用中间人模式传递数据

    中间人模式:如果组件A和组件B要进行通信,他们有共同的父组件,则可以把父组件当中间人,A组件把值发射给父组件,父组件接收后把值通过B组件的Input属性传递给B组件。

    如果两个组件没有共同的父组件,则可以通过服务来订阅事件。

    组件生命周期及angular的变化发现机制

    左边的是组件初始化调用的事件,红色的事件只调用一次,绿色的事件会被多次调用。如果组件有输入属性,则组件在被初始化时会调用ngOnChanges事件。由于这个事件是在构造器之后调用,所以不能在构造函数做初始赋值操作,最好是在ngOnInit方法中做初始化操作。


    组件生命周期
    ngOnChanges什么情况下会被调用

    1、必须是输入属性发生改变
    2、输入属性的地址发生改变,如果输入属性是引用类型,改变该变量的属性值是不会触发ngOnChanges事件

    变更检测和DoCheck钩子

    变更检测是通过zone.js来实现的


    变更检测

    事件会触发变更检测机制,变更检测机制被触发就会调用DoCheck钩子。
    如果钩子上有check的钩子,当触发变更检测机制,所有带check的钩子都会被调用,所以在使用带check的钩子要非常小心。

    @ViewChild装饰器

    可以让父组件获取子组件的引用,调用子组件的方法。

    ngAfterViewInit和ngAfterViewChecked

    这两个方法都是在组件的视图被组装完毕才调用
    如果组件有子组件,只有当所有子组件的视图都被组装完成后,父组件才会被调用
    不要在这两个方法中去改变视图中绑定的东西,如果想改变,要写在定时器里面,不然会抛出异常。

    ng-content标签可以把父组件模板中任意的片段投影到子组件中去。

    ngAfterContentInit和ngAfterContentChecked

    在被投影进来的内容组装完被调用

    ngOnDestroy

    在切换路由的时候调用
    在这个钩子反订阅一个流或者清除定时器

    六、表单处理

    模板式表单

    表单的数据模型通过组件模板中的相关指令来定义的,会受限于HTML的语法,所以,模板式表单只适合用于一些简单的场景。

    NgForm -> FormGroup

    angular会自动为form表单添加ngForm指令,如果不想让它接管,可以在form表单添加ngNoForm指令
    ngForm可以在form之外使用,比如在div中添加
    ngForm可以被模板本地变量引用

    NgModule -> FormControl
    NgModuleGroup -> FormGroup

    响应式表单

    在组件的控制器中创建一个底层的数据模型,然后使用一些特定的指令,将模板上的HTML元素与数据模型连接起来。

    FormControl

    FormGroup

    FormArray
    可以增长的自动集合

    五个指令

    formControl
    formControlName
    formGroup
    formGroupName
    formArrayName
    指令中后面有name的不能使用属性绑定语法,也就是不能加[]
    当formControl和formGroup在一个嵌套里面,则需要加name

    FormBuilder便捷创建数据模型

    表单验证

    angular的校验器

    内置校验器:Validator
    常用的有required, minlength

    自定义校验器

    校验器名(control:FormControl): any{ return null; }

    异步校验器 返回的是一个可观测的流

    校验响应式表单

    判断模板式表单是否有错误,可以用hasError方法。第一个参数是校验器名,第二个参数是校验的属性。如果是嵌套的属性,则传递一个数组,第一个值是一级属性,第二个值是二级属性。

    getError方法可以获取到具体的报错信息

    校验模板式表单

    需要把自定义的校验方法封装为指令,才能在模板中调用

    表单状态字段

    touched和untouched 判断字段是否获取过焦点,用来控制错误信息是否显示

    pristine和dirty 判断字段的值是否修改过

    pending

    相关文章

      网友评论

        本文标题:angular学习笔记

        本文链接:https://www.haomeiwen.com/subject/xwcpoxtx.html