Skip to content

Commit 4f811ae

Browse files
committed
angular end
1 parent 8782dc9 commit 4f811ae

File tree

1 file changed

+207
-7
lines changed

1 file changed

+207
-7
lines changed

_posts/2022-01-27-AngularStudy.md

Lines changed: 207 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ tag: Angular
236236
- 在模板视图中使用管道
237237
- 可以使用CLI命令行`ng g pipe 管道名`<br>
238238
<div align="center" >
239-
<img src=../images/Common_pipe.png width="350" height="350"/>
239+
<img src="/images/Common_pipe.png" width="350" height="350"/>
240240
</div>
241241

242242
```typescript
@@ -386,14 +386,14 @@ tag: Angular
386386
|Axios|也是XHR,只是进一步的封装而已|比原生简单;基于Promise处理响应;可以排队、并发|
387387
|NGHttpClient|也是XHR,只是进一步的封装而已|比原生要简单;基于“观察者模式(23种设计模式之一)”处理响应;可以排队、并发、撤销|
388388
|Fetch|不再是XHR,是W3C提出的新技术,有望取代XHR|比XHR从根本上更加先进;天然基于Promise|
389-
|||
390389
391390
### Angular官方提供的服务对象——HttpClient
392391
- HttpClient服务:是Angular提供的用于发起异步XHR请求的对象
393392
- 使用步骤:
394393
- 1,在主模块中导入HttpClientModule模块
395394
- 2,在组件中声明依赖于HttpClient服务对象,就会被自动注入
396395
- 3,调用HttpClient实例实现异步请求`this.http.get(url).subscribe((res) => {} )`
396+
397397
```typescript
398398
//component.ts页面内容
399399
export class bookcomponent {
@@ -429,14 +429,214 @@ tag: Angular
429429
</table>
430430
<button (click)="loadMore()">加载下一页数据</button>
431431
```
432+
432433
- 4,组件的生命周期钩子函数
433434
- Angular中的组件的声明周期钩子函数调用顺序:
434435
- constructor():组件对象被创建先调用构造函数
435436
- ngOnChanges():组件绑定的属性值发生改变
436437
- <b>ngOnInit()</b>:组件初始化完毕-等同于Vue.js的mounted
437-
- ngDoCheck():开发者自定义变更检测
438-
- ngAfterContentInit():在组件内容初始化后调用
439-
- ngAfterContentChecked():在组件内容每次检查后调用
438+
- ngDoCheck():开发者自定义变更检测
439+
- ngAfterContentInit():在组件内容初始化后调用
440+
- ngAfterContentChecked():在组件内容每次检查后调用
440441
- ngAfterViewInit():在组件视图初始化后调用。
441-
- ngAfterViewChecked():在组件视图每次检查后调用。
442-
- ngOnDestroy():在指令销毁前调用。
442+
- ngAfterViewChecked():在组件视图每次检查后调用
443+
- ngOnDestroy():在指令销毁前调用,组件即将被从DOM树上卸载,适合执行一些资源释放性语句,例如:定时器销毁...
444+
445+
- 5,父子组件传递--重点&难点
446+
447+
```typescript
448+
//创建父组件
449+
export class parentComponent {
450+
userName:string='user'
451+
doCry(e:string){//接收子组件传递的数据
452+
//e为子组件传递过来的数据
453+
this.userName=e
454+
}
455+
456+
//输出父组件内部的识别符的子组件,c0为html中的标识符
457+
@ViewChild('c0',{static:ture})
458+
private child;
459+
print(){
460+
console.log(this.child)
461+
}
462+
463+
}
464+
465+
//创建子组件(更改内容组件)
466+
export class childModifyComponent{
467+
//子=>父,子组件通过触发事件(其中携带者数据),把数据传递给父组件提供事件处理方法
468+
userInput:string = null
469+
470+
//事件发射器
471+
@Output() //输出型属性,可以向父组件传递数据
472+
cryEvent = new EventEmitter()
473+
474+
doModify(){//button (click)绑定事件
475+
//子组将要将数据传递给父组件
476+
//console.log(this.userInput)
477+
this.cryEvent.emit(this.userInput)
478+
}
479+
}
480+
481+
//创建子组件(图片组件)
482+
export class childPhotoComponent {
483+
//普通属性不能被父组件传值
484+
//private childName:string = null
485+
486+
@Input()//父=>子
487+
//输入型属性父组件可以利用这种属性传值,一个装饰器只能装饰一个,多个参数需要多个装饰器
488+
childName:string = null
489+
}
490+
491+
```
492+
```typescript
493+
//parent.html内容中引用事件和参数
494+
<div style="background-color: brown;width: 1000px;height: 1000px;" #c0>
495+
//#XX标识符
496+
<h2>{{userName}}的博客</h2>
497+
498+
//监听子组件的事件
499+
<app-child-modify (cryEvent) = "doCry($event)" #c1></app-child-modify>
500+
<app-child-photo [childName]="userName"></app-child-photo>
501+
</div>
502+
```
503+
504+
### 路由和导航
505+
- 多页面应用:一个项目中有多个完整HTML文件,使用超链接跳转--销毁一棵DOM树,同步请求另一棵,得到之后再重建新的DOM树;不足:DOM树妖反复重建,间隔中客户端一片空白
506+
- 单页面应用:称为SPA(Single Page Application),整个项目中有且只有一个“完整的”HTML文件,其他的“页面”都只是DIV片段;需要哪个“页面”就将其异步请求下来,“插入”到“完整的”HTML文件中。单页应用的优势:整个项目中客户端只需要下载一个HTML页面,创建一个完整的DOM树;页面跳转都是一个DIV替换另一个DIV而已--能够实现过程动画。缺点:不利于SEO访问优化
507+
- Angular中使用“单页应用”的步骤
508+
- 定义“路由词典”——[{URL-组件},{URL-组件},...]
509+
- 为每个路由组件分配一个路由地址
510+
- 注册“路由词典”
511+
- 创建路由组件挂载点——称为“路由出口”
512+
- 访问测试
513+
- 注意:
514+
- 路由词典中的路由地址不能以/开头或结尾,但中间可以包含/
515+
- 路由词典中可以指定一个默认首页地址:`{path:'',component:...}`
516+
- 路由词典中的每个路由要么指定component(由哪个组件提供内容),要么指定redirect(重定向到另一个路由地址)
517+
- 路由词典中可以指定一个匹配任意地址‘**’,注意该地址用于整个路由词典的最后一个
518+
- 路由跳转/导航:从一个路由地址跳转到另一个;实现方案:
519+
- 方法一:使用模板跳转方法<br>
520+
`<any routerLink="/ucenter">`;注意:用于任意标签上,跳转地址应该以/开头,防止以相对方式跳转
521+
```typescript
522+
//在app.module.ts文件中声明路由词典--路由地址和路由组件的对应集合
523+
let routes=[
524+
{path:'index',component:IndexComponent},
525+
{path:'plist',component:ProductListComponent},
526+
{path:'pdetail',component:ProductDetailComponent},
527+
{path:'ucenter',component:UserCenterComponent},
528+
//重定向需要指定“路由地址匹配方式”为“full”或“profix”
529+
{path:'',redirectTo:'pdetail',pathMatch:'full'}
530+
//任意地址,如404网页;**地址匹配任意地址,任意地址不能放在最上面,有顺序的查找
531+
{path:'**',vomponent:NotFoundComponent}
532+
]
533+
534+
@NgModule({
535+
imports:[RouterModule.forRoot(routes)] //导入路由模块,并注册路由词典,用于根模块中
536+
})
537+
538+
//在.html文件中创建路由挂载点
539+
//访问测试通过浏览器打开,如 http://127.0.0.1:4200/index | http://127.0.0.1:4200/ucenter
540+
<router-outlet> </router-outlet>
541+
542+
//传统的超链接可以跳转,但属于DOM树完全重建
543+
<a href="ucenter">进入用户中心</a>
544+
545+
//routerLink可以用在任何标签上的,如按钮、属性等
546+
<a routerLink="/ucenter">进入用户中心</a>
547+
548+
//路由嵌套修改路由词典:
549+
//注意:“用户中心”下的二级路由组件挂载点/路由出口应该放在UserCenter.component.html中
550+
{path:'user/center',
551+
component:IndexComponent,
552+
children:[//嵌套二级路由
553+
{path:'info',component:XXXComponent},
554+
{path:'security',component:XXXComponent},
555+
]},
556+
557+
```
558+
- 方式二:使用脚本方法
559+
- 注意:Router类是RouterModule提供的一个服务类,声明依赖即可使用
560+
```typescript
561+
//在.html文件中
562+
<button (click)="jump()">跳转页面</button>
563+
564+
//在class中依赖注入
565+
export class ParentModule(){
566+
constructor(private router:Router){}
567+
568+
jump(){//跳转到用户中心--需要“路由器”服务
569+
this.router.navigateByUrl('/ucenter')
570+
}
571+
}
572+
```
573+
- Vue.js中的路由跳转的机制有哪些?
574+
1.hash法:只需要修改url中的hash部分:http://127.0.0.1/index.html#/ucenter<br>
575+
2.history法:需要修改window.history对象,从而支持浏览器自带的后退按钮:http://127.0.0.1/ucenter;(Angular只有这种方法)
576+
- 路由参数:
577+
- 在路由词典定义路由地址时,其中可以包含可变的参数:
578+
- 在.html文件中,为路由参数提供具体的参数值
579+
- 到目标路由组件,可以读取“当前路由地址”中的参数
580+
581+
```typescript
582+
//app.module.ts文件
583+
let routers = [ //':'lid表示参数名
584+
{path='producdetail/:lid',component:ProductDetailComponent},
585+
]
586+
587+
//在.html文件中,为路由参数提供具体的参数值
588+
<a routerLink="/producdetail/5">进入5</a>
589+
<a routerLink="/producdetail/13">进入13</a>
590+
<a routerLink="/producdetail/21">进入21</a>
591+
592+
//在producu.component.ts文件中
593+
export class ProductDetailComponent implements Oninit{
594+
private productId:number
595+
596+
//声明依赖:读取参数需要“当前的路由”服务对象
597+
constructor(private route:ActivatedRoute){}
598+
599+
ngOnInit(){
600+
//组件初始化完成,读取路由参数,进而根据此参数查询
601+
this.route.params.subscribe((data)=>{
602+
console.log('得到订阅的路由参数:')
603+
console.log(data)
604+
this.productId = data.lid
605+
})
606+
}
607+
}
608+
```
609+
610+
- 路由守卫:
611+
- Angular提供了“路由守卫(Guard)”来实现访问路由组件前的检查功能:如果检查通过(return true)就放行,如果不通过(return false)不放行
612+
- `ng g guard GuardName`
613+
```typescript
614+
//创建Login.guard.ts文件
615+
@Injectable({ //路由守卫是“可注入”服务对象
616+
providedIn:'root'
617+
})
618+
export class LoginGuard implements CanActivate {
619+
//依赖注入路由
620+
constructor(private router:Router){}
621+
622+
private isLogin = false //此处应该根据用户是否登入而改变
623+
canActivate(){
624+
if(this.isLogin){//可以激活后续的组件
625+
return true
626+
}else{//阻止激活后续的组件
627+
this.router.navigateByUrl('/index')
628+
return false
629+
}
630+
}
631+
}
632+
633+
//在app.module.ts文件中
634+
{path:'user/center',
635+
component:IndexComponent,
636+
//路由守护
637+
canActivate:[LoginGuard],
638+
children:[//嵌套二级路由
639+
{path:'info',component:XXXComponent},
640+
{path:'security',component:XXXComponent},
641+
]},
642+
```

0 commit comments

Comments
 (0)