工作学习angular5笔记

大三上学期,在学校实验室自学的angular1,如今马上毕业了,公司里已经用上了angular5。学起来!!!

组件、服务、路由、指令     

1、环境搭建和快速建立项目

当然,angular5是建立在node6.9版本和npm3.3版本以这两个上的。先全局安装这两个软件吧。

1.1、设置开发环境

全局安装angular5脚手架。Angular CLI :npm install -g @angular/cli

1.2、创建新项目

运行下列命令来生成一个新项目以及应用的骨架代码:ng new my-app (需要耐心等待)

1.3、启动开发服务器

cd my-app

ng serve --open

ng serve命令会启动开发服务器,监听文件变化,并在修改这些文件时重新构建此应用。

使用--open(或-o)参数可以自动打开浏览器并访问http://localhost:4200/

1.4、编辑第一个APP组件

这个CLI为我们创建了第一个Angular组件。 它就是名叫app-root根组件。 你可以在./src/app/app.component.ts目录下找到它。

浏览器会自动刷新,而我们会看到修改之后的标题。不错,不过它还可以更好看一点。

打开 src/app/app.component.css 并给这个组件设置一些样式

1.5、初步了解文件配置

Angular CLI项目是做快速试验和开发企业解决方案的基础。

scr文件夹:你的应用代码位于src文件夹中。 所有的Angular组件、模板、样式、图片以及你的应用所需的任何东西都在那里。 这个文件夹之外的文件都是为构建应用提供支持用的。

根目录:src/文件夹是项目的根文件夹之一。 其它文件是用来帮助你构建、测试、维护、文档化和发布应用的。它们放在根目录下,和src/平级。

2、开始编辑

2.1创建新组件

工作学习angular5笔记_第1张图片

使用 Angular CLI 创建一个名为 heroes 的新组件。ng generate component heroes

         CLI 创建了一个新的文件夹 src/app/heroes/,并生成了 HeroesComponent 的三个文件。

         CLI 自动生成了三个元数据属性:@component是一个装饰器,告诉文件中的typescript的类这是一个组件

     selector— 组件的选择器(CSS 元素选择器)

     templateUrl— 组件模板文件的位置。

     styleUrls 组件私有 CSS 样式表文件的位置。

控制器:

typescript类定义了组件的控制器,是一个被装饰器装饰的typescript的类

   ngOnInit 是一个生命周期钩子,Angular 在创建完组件后很快就会调用 ngOnInit。这里是放置初始化逻辑的好地方。

        始终要 export 这个组件类,以便在其它地方(比如 AppModule)导入它。

工作学习angular5笔记_第2张图片

工作学习angular5笔记_第3张图片

2.2使用第三方类库

2.2.1 把第三方类库安装到本地

例如安装:jQuery和bootstrap

npm install jquery --save

npm install bootstrap --save

2.2.2 把第三方类库进入到项目中去

 修改angular CLI.json文件,scripts属性和css属性中添加文件路径



2.2.3 类型描述文件

因为jQuery是JavaScript的文件,typescript文件是不认识$符号的。所以要在项目中引入类型描述文件

输入命令:npm install @types/jquery --save-dev              npm inastall @types/bootstrap --save-dev

2.2添加属性

往 HeroesComponent 中添加一个 hero 属性,用来表示一个名叫 “Windstorm” 的英雄。

hero = 'Windstorm';

几种定义属性的方法

//定义属性的方法
title='你好angular'; 
//定义属性的方法2
msg:any;

msg1:string='这是一个string类型的msg1';  //定义类型并且赋值

//定义属性加修饰符
public username="张三" 

constructor(){
    this.msg='这是定义属性方法2'
}

工作学习angular5笔记_第4张图片

绑定属性的方法

工作学习angular5笔记_第5张图片

  • 显示heroscomponents视图

要显示 HeroesComponent 你必须把它加到壳组件 AppComponent 的模板中。

别忘了,app-heroes 就是 HeroesComponent 的 元素选择器。 所以,只要把  元素添加到 AppComponent 的模板文件中就可以了,就放在标题下方。

  • 创建hero类

在 src/app 文件夹中为 Hero 类创建一个文件,并添加 id 和 name 属性。

export class Hero { id: number; name: string;}

回到 HeroesComponent 类,并且导入这个 Hero 类。

把组件的 hero 属性的类型重构为 Hero。 然后以1为 id、以 “Windstorm” 为名字初始化它。

import { Component, OnInit } from '@angular/core';
import { Hero } from '../hero';

@Component({
  selector: 'app-heroes',
  templateUrl: './heroes.component.html',
  styleUrls: ['./heroes.component.css']
})
export class HeroesComponent implements OnInit {
  hero: Hero = {
    id: 1,
    name: 'Windstorm'
  };
  constructor() { }
  ngOnInit() {
  }
}

页面显示变得不正常了,因为你刚刚把 hero 从字符串改成了对象。

  • 显示hero对象

修改模板中的绑定,以显示英雄的名字,并在详情中显示 id 和 name,就像这样:

  • 使用uppercasepipe进行格式化

把 hero.name 的绑定修改成这样:

{{ hero.name | uppercase }} Details

管道  是格式化字符串、金额、日期和其它显示数据的好办法。 Angular 发布了一些内置管道,而且你还可以创建自己的管道。
  • 编辑英雄名字

2.3双向数据绑定

[(ngModel)] 是 Angular 的双向数据绑定语法。[(ngModel)] 不可以改变

这里把 hero.name 属性绑定到了 HTML 的 textbox 元素上,以便数据流可以双向流动:从 hero.name 属性流动到 textbox,并且从 textbox 流回到 hero.name 。

缺少formsmodule,实现双向数据绑定需要引入formsmodule模块,还要在app.modules导入

虽然 ngModel 是一个有效的 Angular 指令,不过它在默认情况下是不可用的。

它属于一个可选模块FormsModule,你必须自行添加此模块才能使用该指令。

  • appmodule

导入formsmodule

打开 AppModule (app.module.ts) 并从 @angular/forms 库中导入 FormsModule 符号。

import { FormsModule } from '@angular/forms'; // <-- NgModel lives here
然后把  FormsModule  添加到  @NgModule  元数据的  imports  数组中,这里是该应用所需外部模块的列表。
imports: [
  BrowserModule,
  FormsModule
],
  • 声明heroscomponents

每个组件都必须声明在(且只能声明在)一个 NgModule 中。

2.4事件对象表单处理

//事件对象 
  
//键盘弹起
keyupFn(e){
    console.log(e);
    if(e.keyCode==13){   //键盘回车键keycode
        alert('按下回车键');
}
}

3、创建模拟数据

创建模拟mock数据

显示这些数据

你要在 HeroesComponent 的顶部显示这个英雄列表。

打开 HeroesComponent 类文件,并导入模拟的 HEROES

import { HEROES } from '../mock-heroes';

往类中添加一个 heroes 属性,这样可以暴露出这些英雄,以供绑定。

heroes = HEROES;

使用*ng-for使用这些数据

 
  • {{hero.id}} {{hero.name}}

*ngFor 是一个 Angular 的复写器(repeater)指令。 它会为列表中的每项数据复写它的宿主元素。

在这个例子中

  •  就是 *ngFor 的宿主元素

  • heroes 就是来自 HeroesComponent 类的列表。

  • 当依次遍历这个列表时,hero 会为每个迭代保存当前的英雄对象。

4、主从结构

添加click事件绑定

  • 这是 Angular 事件绑定 语法的例子。

    click 外面的圆括号会让 Angular 监听这个 

  •  元素的 click 事件。 当用户点击 
  •  时,Angular 就会执行表达式 onSelect(hero)

    onSelect() 是 HeroesComponent 上的一个方法,你很快就要写它。 Angular 会把所点击的 

  •  上的 hero 对象传给它,这个 hero 也就是以前在 *ngFor 表达式中定义的那个。

    添加click事件处理器

    5、服务

    为什么需要服务?:把数据访问的职责委托给服务。

    创建一个heroserives服务,应用中所有的类都可以利用他来获取英雄列表。不用使用new来创建此服务,而要依靠angular的依赖注入机制把它注入到 HeroesComponent 的构造函数中。

    工作学习angular5笔记_第6张图片

    服务是在多个“互相不知道”的类之间共享信息的好办法。 你将创建一个 MessageService,并且把它注入到两个地方:

    1. HeroService 中,它会使用该服务发送消息。

    2. MessagesComponent 中,它会显示其中的消息。

    5.1 angular CLI 创建服务

    工作学习angular5笔记_第7张图片

    创建服务命令:

    工作学习angular5笔记_第8张图片

    例如:使用 Angular CLI 创建一个名叫 hero 的服务。ng generate service hero

    5.2 app.module.ts 里面引入所创建的服务

    工作学习angular5笔记_第9张图片

    5.3 使用服务的组件引入服务,注册服务


    注意:依赖注入服务写到括号里面不是花括号里面。

    @injectable()服务

    5.4 使用服务

    在服务文件中创建服务

    工作学习angular5笔记_第10张图片

    在模板组件中使用服务

    工作学习angular5笔记_第11张图片

    HeroService.getHeroes() 必须具有某种形式的异步函数签名

    它可以使用回调函数,可以返回 Promise(承诺),也可以返回 Observable(可观察对象)。

    Observable(可观察对象)版本的HeroService

    Observable 是 RxJS 库中的一个关键类。

    6、路由

    可以把路由器理解:为控制整个应用视图状态的对象,每个应用都有一个路由器,配置路由器以满足需求。

    为每个视图分配一个特定的URL,这样就可以是应用直接跳到某个特定的视图中。

    6.1添加APPRoutingModule。

    加载和配置路由器,他专注于路由功能,然后由根模块导入它APPModule。

    ng generate module app-routing --flat --module=app

    --flat  把这个文件放进了  src/app  中,而不是单独的目录中。
    --module=app  告诉 CLI 把它注册到  AppModule  的  imports  数组中。

    通常不会在路由模块中声明组件

    6.2了解路由的基础知识,五个路由对象:

    工作学习angular5笔记_第12张图片路由对象和使用的位置:

    工作学习angular5笔记_第13张图片

    Routes对象:

    注意:path变量中不能加入斜杠开头,因为angular路由器会为我们解析生成URL,不使用斜杠开头可以自由的用绝对路径和性对路径来切换。


    Router对象:

    工作学习angular5笔记_第14张图片

    RouterOutlet:(插座)指示当前某一个导航的路由的时候,组件视图显示的地方。


    routerLink对象: 跟路由


    在路由时传递数据:

    1.在查询参数种传递数据

    /product?id=1&name=2 => ActivaedRoute.queryParams[id];

    举例:

    商品详情
    export class ProductComponent implements OnInit {
      private productId: number;
      constructor(private routerInfo: ActivatedRoute) { }
    
      ngOnInit() {
        this.productId = this.routerInfo.snapshot.queryParams['id'];
      }
    
    }

    2.在路由路径(URL)中传递数据??? 小练习中不能实现

    {path:/product/:id} => /product/1  =>  ActivatedRoute.params[id]

    举例:

    export class ProductComponent implements OnInit {
      private productId: number;
    
      constructor(private routerInfo: ActivatedRoute) { }
    
      ngOnInit() {
        this.productId = this.routerInfo.snapshot.params['id'];
      }
    
    }
    商品详情 

    app-routingcomponent

      {path: 'product/id', component: ProductComponent}, // 修改路由中的path属性使其可以携带参数

    3.路由配置中传递数据

    {path:/product, component:ProductComponent,data:[{isProd:true}]}
                      =>  ActivatedRoute.data[0][isProd]

    参数快照:

      private productId: number;
    
      constructor(private routerInfo: ActivatedRoute) { }
    
      ngOnInit() {
        this.productId = this.routerInfo.snapshot.params['id'];
      }

    参数订阅:

     ngOnInit() {
        this.routerInfo.params.subscribe((params: Params) => this.productId = params["id"]);
       this.productId = this.routerInfo.snapshot.params['id'];
      }

    重定向路由

     在用户访问一个特定的地址时,将其重定向到另一个指定的地址。

    工作学习angular5笔记_第15张图片

     // 路由重定向,重定向到home的路由上
      {path: '', redirectTo: '/home', pathMatch: 'full'},
      {path: 'home', component: HomeComponent},

    子路由

    工作学习angular5笔记_第16张图片

    辅助路由:

    
    
    //路由配置
    {path:'xxx',comment:XxxComponent,outlet:"aux"}
    {path:'yyy',comment:yyyComponent,outlet:"aux"}
    //链接
    xxx
    yyy

    路由守卫:

    应用场景:例如

    1. 只有当用户登录并拥有某些权限时才能进入某些路由
    2. 一个路由多个表单组件组成的向导,例如注册流程,用户只有在当前路由的组建中填写了满足要求的信息才可以导航到下一个路由
    3. 当用户未执行保存操作而试图离开当前导航时提醒用户

    CanActivate:处理导航到某路由的情况。

    CanDeactivate:处理当前路由离开的情况。

    Resolve:在路由激活之前获取路由数据。

    Resolve:

    可以预先在进入路由之前去服务器上读数据,把需要的数据带到视图里面显示出来


    需要使用RouterModule中的Routes类来配置路由器,所以还需要从@angular/router库中导入这两个符号。

    添加一个@ngModule.exports数组,其中放上RouterModule.

    导出RouterModule路由器的相关指令,可以在APPModule中的组件使用。

    • 添加路由器定义

    典型的 Angular 路由(Route)有两个属性:

    1. path:一个用于匹配浏览器地址栏中 URL 的字符串。

    2. component:当导航到此路由时,路由器应该创建哪个组件。

    首先要导入  HeroesComponent ,以便能在  Route  中引用它。 然后定义一个路由数组,其中的某个路由是指向这个组件的。
    import { HeroesComponent }      from './heroes/heroes.component';
    
    const routes: Routes = [
      { path: 'heroes', component: HeroesComponent }
    ];

    RouterModule.forRoot()

    必须先初始化路由器,并让开始监听浏览器的地址变化

    把RouterModule,添加到@ngimports数组中,并用routes来配置。只需要调用imports数组中的RouterModule.forRoot()函数就可以了。

    添加路由出口RouterOutLet

    7、HTTP

    启动http服务

    httpclient是angular通过http与远程服务的机制。

    模拟数据服务

    通过httpclient获取英雄

    http方法返回单个值

    所有的httpclient都会返回某个值的RxJSobservable

    http是一个请求响应协议,你发送请求他返回单个的响应

    httpclient.get返回响应数据

    HttpClient.get 默认情况下把响应体当做无类型的 JSON 对象进行返回。 如果指定了可选的模板类型 ,就会给返回你一个类型化的对象。

    错误处理

    凡事皆会出错,特别是当你从远端服务器获取数据的时候。 HeroService.getHeroes() 方法应该捕获错误,并做适当的处理。

    要捕获错误就要使用RXJS的catchError操作符来建立对observable的结果处理的管道。

    catchError() 操作符会拦截失败的Observable。 它把错误对象传给错误处理器错误处理器会处理这个错误。

    下面的 handleError() 方法会报告这个错误,并返回一个无害的结果(安全值),以便应用能正常工作。

    如果你忘了调用 subscribe(),本服务将不会把这个删除请求发送给服务器。 作为一条通用的规则,Observable 在有人订阅之前什么都不会做

    8、模板与数据绑定

    8.1 显示数据

    最典型的数据显示方式就是把html中的模板中的控件绑定到angular组件的属性。

    使用插值表达式显示组件属性

    使用差值表达式就是把属性名包裹在双花括号里放进视图模板。

    使用ng-for,显示数组属性

    为数组创建一个类:

    对对象数组的绑定,需要把数组抓换成对象数组

    使用该

    8.2模板语法

    组件扮演着控制器或视图模型的角色,模板则扮演视图的角色

    通过数据绑定来动态获取/设置dom对象的

    对花括号中的表达式求职,把求职的结果转化成字符串。

    模板表达式:

    模板表达式产生一个值,并把它赋值给绑定属性的目标。

    typescript和JavaScript的区别

    JavaScript 中那些具有或可能引发副作用的表达式是被禁止的,包括:

    • 赋值 (=+=-=, ...)

    • new 运算符

    • 使用 ; 或 , 的链式表达式

    • 自增或自减操作符 (++ 和 --)

    和 JavaScript 语 法的其它显著不同包括:

    • 不支持位运算 | 和 &

    • 具有新的模板表达式运算符,比如 |?. 和 !

    表达式上下文

    表达式的上下文可以包括组件之外的对象。 比如模板输入变量 (let hero)和模板引用变量(#heroInput)就是备选的上下文对象之一。

    表达式指南:

    没有可见的副作用,除了目标属性值以外不应该改变应用的任何状态。

    模板语句:

    模板语句用来绑定由绑定目标出发的事件

    语句上下文

    模板语句不能引用全局命名空间的任何东西,比如不能引用window或document

    绑定语法:概览

    绑定的类型可以根据数据数据流的方向分成三类,

    从数据源到视图:

    从视图到数据源:

    从视图到数据再到视图:

    模板是通过property和事件来工作的,而不是anttribute

    绑定目标:

    属性绑定:属性名

    最常见的属性绑定是把元素的属性设置为组件的属性,

    还有重要一种是设置自定义组件的模型属性

    单项输入

    绑定目标:目标的名字总是property的名

    一次性字符串初始化

    属性绑定还是差值表达式?但数据类型不是字符串时,就必须使用属性绑定了。要渲染的是字符串时两种都可以。

    css绑定?

    样式绑定:

    通过绑定可以设置内联样式:样式绑定与属性绑定类似

    事件绑定:

    反向数据流:从元素到组件。左侧带圆括号的目标事件和右侧引号中的模板事件。

    目标事件:

    $event和事件处理语句

    事件绑定中angular回为目标事件设置事件处理器。绑定会通过$event事件对象来传递信息。

    事件对象的形态取决于目标事件

    双向数据绑定:

    双向数据绑定语法:盒子里的香蕉

    内置指令:

    内置属性型指令:

    ng-class:

    ng-style:可以根据组件的样式动态设置,可以同时设置多个内联样式:

    ng-model:使用之前需要导入formsmodule,并添加到imports列表中

    内置结构型指令:

    结构性指令的职责是html布局:

    ng-if:

    通过把ng-if指令应用到元素上称为宿主元素,往dom中添加或从dom中移除这个元素。

    这和显示和隐藏式不同的。

    当隐藏子树时,它仍然留在 DOM 中。 子树中的组件及其状态仍然保留着。 即使对于不可见属性,Angular 也会继续检查变更。 子树可能占用相当可观的内存和运算资源。

    可以用来防范空指针错误。?什么是空指针错误

    ngforof:

    是一个重复器指令,-自定义数据显示的一种方式 。目标是展示由多个条目组成的列表。

    带索引的ng-for

    ng-switch:

    他可以从多个可能的元素中根据switc hh条件来显示某一个。只会把选中的加入到dom元素中。

    主控指令,要把它保存到一个返回候选值得表达式,

    绑定到 [ngSwitch]。如果试图用 *ngSwitch 的形式使用它就会报错,这是因为 NgSwitch 是一个属性型指令,而不是结构型指令。 它要修改的是所在元素的行为,而不会直接接触 DOM 结构。

    绑定到 *ngSwitchCase 和 *ngSwitchDefault NgSwitchCase 和 NgSwitchDefault 指令都是结构型指令,因为它们会从 DOM 中添加或移除元素。

    模板引用变量:

    模板引用变量通常用来引用模板中的某个dom元素,

    模板引用变量怎么得到他的值?

    模板引用变量的作用范围是整个模板,不要在同一模板中多次定义同一变量名

    输入和输出属性:
    输入属性是一个带有input装饰器的可设置属性。

    9、表单处理事件对象

    //事件对象 
      
    //键盘弹起
    keyupFn(e){
        console.log(e);
        if(e.keyCode==13){   //键盘回车键keycode
            alert('按下回车键');
    }
    }




  • 你可能感兴趣的:(学习笔记)