angular服务
里面可以写公共的方法当每个组价想要使用的时候都可以去调用(有点感觉像vue中的vuex)
创建服务
代码式创建
ng g service services/服务名,创建好之后进入引入并配置如下图
使用服务
第一种(官网不推荐这种)
// 引入storage服务
import { StorageService } from '../../services/storage.service'
let storage = new StorageService();
//因为StorageService是一个class所以我们可以进行new来实例化,但是这种方法官方是不推荐的
constructor() {
storage.get();//此时这里就可以调用
};
第二种
此时跟第一种一样的效果
// 引入storage服务
import { StorageService } from '../../services/storage.service'
constructor(private storage:StorageService) {
//这个参数同时做了两件事:1. 声明了一个私有 storage属性,2. 把它标记为一个 StorageService的注入点。
this.storage.get();//此时这里就可以调用
};
组件可以调用服务但是服务不能去调用组件,服务和服务之间也是可以调用的。
angular操作DOM
原生操作Dom
html
<div id="box">box</div>
<div id="box1" *ngIf="flag">box1</div>
ts
ngOnInit(): void {
// 原生获取DOM节点
let box = document.querySelector('#box');
console.log(box?.innerHTML);
let box1 = document.getElementById('box1');
console.log(box1?.innerHTML);//此时运行程序没有问题,但是这里输出的undefined
//因为这个周期函数里,只是组件和指令的初始化完成并不是真正的Dom加载完成
};
ngAfterViewInit():void{//此时在这个周期函数里面Dom才是真正加载完成
let box1 = document.getElementById('box1');
console.log(box1?.innerHTML);
angular操作Dom
html
<div #box2>box2</div>
<div #box3>box3</div>
ts
首先要引入 ViewChild
下面两行写在类中
@ViewChild("box2") box2:any;
@ViewChild("box3") box3:any;
还是在刚才那个周期函数里面
ngAfterViewInit():void{//此时在这个周期函数里面Dom才是真正加载完成
console.log(this.box2);
console.log(this.box3);
console.log(this.box3.nativeElement.innerHTML);//此时这样就可以获取了
}
使用ViewChild调用子组件的方法
html
<button (click)='getChildFun()'>调用子组件的run方法</button>
<!-- 加入子组件 -->
<app-news #appNews></app-news>
ts
@ViewChild("appNews") appNews:any;
getChildFun():void{
this.appNews.run();//此时就是调用子组件的方法,需要在子组件定义此方法
};
angular组件之间的通信
父传子
//在父组件传入
<app-header [msg]="msg"></app-header>
//在子组件引入模块
import{ Input }from '@angular/core';
//在子组件接收
@Input() msg?:string
//还可以把整个父组件传给子组件
<app-header [home]="this"></app-header>
@Input() msg:any
子传父
//子组件通过@viewChild主动获取子组件的数据和方法
<app-header #headerChild></app-header>
//引入ViewChild
import {Component,OnInit,ViewChild} from '@angular/core'
//ViewChild和刚才的子组件关联起来
@ViewChild {"headerChild"} header;
//调用子组件的属性和方法
this.header.xxxx
通过@Output触发父组件的方法
//子组件引入Output和EventEmitter
import {Component,OnInit,Input,Output,EventEmitter} from '@angular/core'
//子组件中实例化EventEmitter
@Output() private outer=new EventEmitter<string>(); /*用EventEmitter和output装饰器配合使用 <string>指定类型变量*/
//子组件通过 EventEmitter 对象 outer 实例广播数据
sendParent(){
// alert('zhixing');
this.outer.emit('msg from child')
}
//父组件调用子组件的时候,定义接收事件 , outer 就是子组件的 EventEmitter 对象 outer
<!--$event就是子组件emit传递的数据-->
<app-header (outer)="runParent($event)"></app-header>
//父组件接收到数据会调用自己的 runParent 方法,这个时候就能拿到子组件的数据
//接收子组件传递过来的数据
runParent(msg:string){
alert(msg);
}
非父子组件通讯
- 公共的服务
- 本地储存 localstorage sessionstorage
- Cookie
生命周期
顺序
ngOnChange()
用途:当 Angular 设置或重新设置数据绑定的输入属性时响应。 该方法接受当前和上一属性值的 SimpleChanges 对象
注意,这发生的非常频繁,所以你在这里执行的任何操作都会显著影响性能
时机:如果组件绑定过输入属性,那么在 ngOnInit() 之前以及所绑定的一个或多个输入属性的值发生变化时都会调用。
注意,如果你的组件没有输入属性,或者你使用它时没有提供任何输入属性,那么框架就不会调用 ngOnChanges()。
ngOnInit() 数据初始化一般在这个周期函数里
用途:在 Angular 第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件
时机:在第一轮 ngOnChanges() 完成之后调用,只调用一次。而且即使没有调用过 ngOnChanges(),也仍然会调用 ngOnInit()(比如当模板中没有绑定任何输入属性时)。
ngDoCheck()
ngAfterContentInit()
ngAfterContentChecked()
ngAfterViewInit() DOM加载完之后的周期 要进页面操作DOM可在该周期里
用途:当 Angular 初始化完组件视图及其子视图或包含该指令的视图之后调用。
ngAfterViewChecked()
ngOnDestroy() 组件销毁前
用途:每当 Angular 每次销毁指令/组件之前调用并清扫。 在这儿反订阅可观察对象和分离事件处理器,以防内存泄漏