摘要:最近在看,随手记的一些的随笔。新上手或者准备学的可以用作参考,第一次写博客,笔记不算完整,若老司机发现有不足指出请指出。处理当前路由离开的情况。在路由激活之前获取路由数据。
最近在看angular4,随手记的一些angular的随笔。
新上手或者准备学angular的可以用作参考,第一次写博客,笔记不算完整,若老司机发现有不足指出请指出。
技术交流群:513590751
Angular程序架构组件
是Angular应用的基本构件块、可以把一个组件理解为一段带有业务逻辑和数据的html指令 详细指令速查
允许向html添加自定义行为模块
用来将应用中不同的部分组成一个Angular框架可以理解的单元
服务
用来封装可重用的业务逻辑组件 在组件上声明模版变量
#varName组件元数据装饰器
用来元数据附加到typescript的类上面 从而让angular把这个类识别为组件 ## selecter:css的选择器,标志可以根据该选择器作为html标签 ## templateUrl:指定了html文件作为组件的模版 ## styleUrls:指定了组件模版中的样式控制器
控制器是指被@component()装饰的类 包含与模版相关的所有的属性与方法 与页面相关的大部分逻辑都是编写在控制器里面模块 @NgModule装饰器
用@NgModule装饰器生成一个模块 ## 用declarations声明了模块中有什么东西(只能声明组件、指令和管道) ## 用imports声明了模块依赖的其他模块 ## 用providers声明模块中提供什么服务(此处只能声明服务) ## 用bootstrap声明了模块的主组件 ## 在模块中声明服务,在所有组件中都可以使用,在组件中声明服务,只能在组件中使用(每个想要被注入的服务都需要在服务提供其中声明)新建一个Angualr项目 用angular-cli创建一个angular项目
创建:ng new my-app 启动:ng serve [--open] --open:在浏览器打开 --routing:生成一个带route的项目 生成组件:ng g component [componentName] 生成服务:ng g service [serviceName] 生成管道:ng g pipe [pipeName] 生成指令:ng g directive [directiveName]Angular router
名称 | 简介 |
---|---|
Routes | 路由配置,保存着哪个URL对应展示哪个组件,以及在哪个RouterOutlet中展示组件 |
Routerlet | 在HTML中标记路由内容呈现位置的占位符指令 |
Router | 负责在运行时执行路由的对象,可以通过调用其navigate()和navigateByUrl()方法来导航到一个指定的路由 |
RouterLink | 在HTML中声明路由导航用的指令 |
ActivatedRoute | 当前激活的路由对象,保存着当前路由的信息,如路由地址,路由参数等 |
path:路由URL component:路由对应的组件 {path:"**",component:Page404Component} //404页面,放到所有路由的最后 children:[{path:"aaa",component:AaaComponent}]子路由 redirectTo:重定向的URL pathMatch:指定匹配方式,匹配path中的 "",(full完全匹配,prefix匹配前缀) loadChildren:延迟加载 canActivate:[class] //此处调用的类需要在providers里面声明,该类实现了CanActivate类 implements CanActivate canDeactivate:[class] //此处调用的类需要在providers里面声明,该类实现了CanDeactivate类 implements CanDeactivate路由时传递参数resolve:{param1:value1,params2:value2} //此处调用的类需要在providers里面声明,该类实现了Resolve类 implements Resolve
传参: 方式1:/product?id=1&name=2 方式2:{path:/product/:id} => /product/1 方式3:{path:/product,component:ProductComponent,data:[{flag:true}]} 取值:ActivatedRoute.queryParams[id] //适用于方式1 ActivatedRoute.params[id] //适用于方式2 ActivatedRoute.data[0][flag] //适用于方式3参数快照
export class ProductComponent implements OnInit { private name; private id; constructor(private activatedRoute: ActivatedRoute) { } ngOnInit() { // 订阅方式 如果会有组件调用本身的情况就使用订阅方式 this.activatedRoute.params.subscribe((params: Params ) => this.id = params["id"] ); // 快照方式 this.name = this.activatedRoute.snapshot.queryParams["name"]; this.id = this.activatedRoute.snapshot.params["id"]; } }辅助路由
路由守卫{path:"xxx",component:XxxComponent,outlet:"aux"} {path:"yyy",component:YyyComponent,outlet:"aux"} xxx yyy primary:控制主路由
CanActivate:处理导航到某路由的情况。 CanDeactivate:处理当前路由离开的情况。 Resolve:在路由激活之前获取路由数据。依赖注入
在providers中注册接口 在需要引用的类的构造方法的参数中注入 constructor(private params1:Params){} 当使用同一个接口不同的实现类时,在providers中声明providers: [{ provide: Params, useClass: AnotherParams }] 使用工厂类确定使用哪个类时,在providers中声明providers:[{ provide: Params, useFactory: () => { let depClass = new DepClass(); // 此处工厂方法和DepClass类耦合 let isLogin = Math.random() > 0.5; // 可能还依赖一个外部的变量来判断需要创建哪个类 //在这里返回要使用的类型 注意:工厂方法只会在创建第一个需要注入的对象的时候被调用一次 } },DepClass] // 为工厂方法解耦合 使用deps属性来声明工厂方法依赖的类和变量的provide属性,在providers中声明providers:[{ provide: Params, useFactory: (depClass:DepClass,isLogin) => { //在这里返回要使用的类型 }, deps: [DepClass,"IS_LOGIN_ENV"] },DepClass,{ provide:"IS_LOGIN_ENV", useValue:false }] useValue的值可以是基本类型,也可以是对象类型 angular会吧工厂方法依赖的DepClass类注入到工厂方法数据绑定 使用插值表达式
使用方括号将html标签的一个属性绑定到一个表达式上{{productTitle}}
使用小括号将组件控制器的一个方法绑定为模版上一个事件的处理器 $event(浏览器事件对象)指向触发事件的dom元素
事件中使用 event.target.value 获取的值是html元素的dom属性(dom属性的值是会发生变化的)
使用 event.target.getAttribute("value") 获取的值是html元素的初始值(html属性是不会发生变化的)双向数据绑定这种方式会替换原class属性的值这种方式不会替换原class属性的值这种方式可以控制多个属性的显示
管道双向数据绑定
{{name | filter}} eg:{{birthday | data}}// 将生日转化成日期格式 eg:{{birthday | data:"yyyy-MM-dd HH:mm:ss"}}// 将生日转化成指定日期格式自定义管道
在项目中生成一个管道,然后在管道类的transform方法中对值进行操作。
export class PipeName implements PipeTransform { transform(value: any, arg: any): any { // value 是要在管道做处理的值 // arg 是管道后面跟着的参数 } }响应式编程
1、在项目模块中引入ReactiveFormsModule模块 2、在组件中声明FormControl类型的字段 eg:formControlName 3、在页面中控件上声明[formControl]="formControlName" 4、在组件中订阅formControlName的valueChanges事件 eg:this.formControlName.valueChanges.subscribe(value => this.keyword = value);组件间通讯 组件的输入输出属性
在需要注入的属性上用@Input注解 在父组件中用[propName]="value"来赋值
在子组件属性上用@Output解属性类型为EventEmitter使用中间人模式传递数据类型 @Output() prop:EventEmitter = new EventEmitter(); 用 prop.emit(dataTypeObj) 在父组件中声明dataTypeObj:DataType = DataType();//用来存放子组件Output出来的属性 在父组件引用子组件的标签上用事件订阅来订阅自组建发射的事件 用 // 监控的事件名 prop 和@Output中的参数一致,不传参时默认和属性名一致 在父组件中声明 propHandler(event:DataType){ // 把子组件Output出来的属性赋值到父组件的属性上 this.dataTypeObj = event; }
两个子组件,通过@Output数据到父组件和@Input从父组件接收数据来实现组件间通讯,父组件为中间人组件生命周期以及angular的变化发现机制
想要使用这些钩子,需要先实现对应的接口 被调用一次的钩子 constructor(组件构造方法,调用该方法时,组件的输入属性没有值) ngOnInit(初始化组件或指令,调用该方法时,OnChanges方法已被调用,组件的输入属性有值) ngAfterContentInit(和angular的内容投影相关的) ngAfterViewInit(和angular的视图初始化和检查相关的,在此方法不可修改组件的属性) ngOnDestroy(组件销毁,在路由到其他组件时当前组件被销毁) 被调用多次的钩子 ngOnChanges(父组件初始化或修改子组件的输入属性的值的时候被调用,如果一个方法没有输入属性,则该方法不会被调用) ngDoCheck(用来检测,在每个angular的变更检测周期调用) ngAfterContentChecked(和angular的内容投影相关的) ngAfterViewChecked(和angular的视图初始化和检查相关的,在此方法不可修改组件的属性) 调用顺序: constructor、ngOnChanges、ngOnInit、ngDoCheck、ngAfterContentInit、ngAfterContentChecked、ngAfterViewInit、ngAfterViewChecked、ngAfterContentChecked、ngAfterViewChecked
#在父组件的模块中调用子组件的方法 1、在子组件上声明模版变量 #childName 2、在父组件中声明一个类型为 ChildeComponent 的变量 child 3、用 @ViewChild("childName") 注解声明的变量 child 4、在代码块中用 this.child.methodName(args) 来调用子组件的方法 #在父组件的模版中调用子组件的方法 1、在子组件上声明模版变量 #childName 2、在父组件的模版中绑定事件 (click)="childName.methodName("args")"父组件内容投影到子组件中
#父组件表单处理 模版式表单#子组件 这是头部定义单个投影点时可以不写class属性和select属性
表单的数据模型是通过组件模版中的相关指令来定义的,因为使用这种方式定义表单的数据模型时,我们会受限与HTML的语法,所以,末班驱动方式只是用于一些简单的场景可用指令
NgForm NgModel NgModelGroup 用#myForm来声明表单的模版变量,在表单的onSubmit="onSubmit(myForm.value,myForm.valid)"来传入表单的值和表单是否通过验证生成指令
@Directive({ selecter: "[dirName]", // 在html上作为属性使用 providers: [{provide: NG_VALIDATORS, useValue: mobileValidator, multi: true}] // mobileValidator是已经声明的验证器 })响应式表单
使用响应式表单时,通过编写TypeScrtipt代码而不是HTML代码来创建一个底层的数据模型,在这个模型定义好以后,使用一些特定的指令,将模版上的HTML元素与底层的数据模型连接在一起可用对象
FormControl userinfo: FormControl = new FormControl("aaa"); FormGroup FormGroup是多个FormControl的集合 FormArray使用
方式一、 formModel: FormGroup = new FormGroup({ username: new FormControl("初始值"), password: new FormControl(), email: new FormArray([ "a", "b" ]) }); 方式二、 constructor(fb: FormBuilder){ this.formModel = fb.group({ username: ["初始值", Validators.required], // 第二个参数是校验器,可以传一个数组,第三个参数是异步校验器 password: [""], email: fb.array([ "a", "b" ]) }); }表单验证 校验器
funcName(control: AbstractControl) {[key: string]: any} { return null; } eg: mobileValidator(control: FormControl) any { let valid = true; return valid ? null : {mobile : true}; } constructor(fb: FormBuilder){ this.formModel = fb.group({ mobile: ["", this.mobileValidator] }); } onSubmit() { let isValid:boolean = this.formModel.get("username").valid; // 获取字段是否通过验证 let error:any = this.formModel.get("username").errors; //获取字段未通过验证的错误信息 this.formModel.valid; // 用来判断表单是否合法 }异步校验器
异步校验器作为字段构造的第三个参数传入 funcName(control: AbstractControl) {[key: string]: any} { // 返回的对象用Observable.of方法包裹,delay延迟5s return Observable.of({}).delay(5000); } eg: mobileAnsycValidator(control: FormControl) any { let valid = true; return Observable.of(valid ? null : {mobile : true}).delay(5000); } constructor(fb: FormBuilder){ this.formModel = fb.group({ mobile: ["", this.mobileValidator, this.mobileAnsycValidator] }); }与服务器通讯 引入Http模块:
1、import Http from "@angular/http"; 2、在cunstructor方法中注入:cunstructor(http: Http) 3、使用this.http.get("url",data)获取数据,并且用.map(res => res.json())把获取到的数据转换成json格式 4、用Observable类型的变量接收数据 5、订阅Observable类型的变量,并且用obs.subscribe(data => this.product = data)来赋值给变量 proxy.conf.json配置 // 意指当前请求是以/api开头时,把请求转发到http://loacalhost:8000 { "/api": { "target": "http://loacalhost:8000" } } // 在package.json中配置 ng serve 命令添加参数 --proxy-config proxy.conf.json使用websocket协议与后台通信 service
import {Injectable} from "@angular/core"; import {Observable} from "rxjs/Observable"; @Injectable() export class WebSocketService { ws: WebSocket; constructor() { } // 根据传入的url创建一个websocket协议 createObservableScoket(url: string): Observablecomponent{ // 创建websocket服务 this.ws = new WebSocket(url); return new Observable(observer => { // 返回成功时执行的方法 this.ws.onmessage = event => observer.next(event.data); // 返回错误时执行的方法 this.ws.onerror = event => observer.error(event); // 关闭websocket流时执行的方法 this.ws.onclose = event => observer.complete(); }); } sendMessage(msg: string) { this.ws.send(msg); } }
export class SearchComponent implements OnInit { constructor(private wsService: WebSocketService) { } ngOnInit() { // 订阅websocket返回的值 this.wsService.createObservableScoket("ws://localhost:8085").subscribe( data => console.log(data), error => console.log(error), () => console.log("webSocket已结束!") ); } }
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/83192.html
摘要:最近在看,随手记的一些的随笔。新上手或者准备学的可以用作参考,第一次写博客,笔记不算完整,若老司机发现有不足指出请指出。处理当前路由离开的情况。在路由激活之前获取路由数据。 最近在看angular4,随手记的一些angular的随笔。 新上手或者准备学angular的可以用作参考,第一次写博客,笔记不算完整,若老司机发现有不足指出请指出。 技术交流群:513590751 Angular...
摘要:博主目前的这个项目还不算很大,模块依赖简单,但期望完成诸如版本号替换,压缩代码,合并文件,发布到服务器等和模块化关系不大的工作,所以使用了。同时,对和附加缓存,配合和版本号实现服务器更新,这一部分其实已经帮我们实现好了。 经常在各种论坛、博客还有 github 上活跃的朋友不难发现,许多大牛都有自己的网站,也多以博客为主。博主作为一个立志前端的大白,难道不应该和大牛学习么?说干就干,前...
摘要:博主目前的这个项目还不算很大,模块依赖简单,但期望完成诸如版本号替换,压缩代码,合并文件,发布到服务器等和模块化关系不大的工作,所以使用了。同时,对和附加缓存,配合和版本号实现服务器更新,这一部分其实已经帮我们实现好了。 经常在各种论坛、博客还有 github 上活跃的朋友不难发现,许多大牛都有自己的网站,也多以博客为主。博主作为一个立志前端的大白,难道不应该和大牛学习么?说干就干,前...
阅读 3126·2021-10-08 10:04
阅读 1038·2021-09-30 09:48
阅读 3427·2021-09-22 10:53
阅读 1629·2021-09-10 11:22
阅读 1660·2021-09-06 15:00
阅读 2122·2019-08-30 15:56
阅读 685·2019-08-30 15:53
阅读 2220·2019-08-30 13:04