1. angular获取不到DOM结点
angular中的ngOnInit
钩子函数获取不到DOM节点;
这个钩子函数中,表示组件和指令初始化完成,并不是真正的DOM加载完成;
所以这时候需要利用另外一个钩子函数ngAfterViewInit()
,是在视图加载完成之后触发,这时候就一定能获取到DOM了;所以建议将DOM操作放到ngAfterViewInit()函数中;
这时,box1的颜色才会变为蓝色;
但是这里要注意,当html中的DOM没有写任何angular的指令,比如像ngIf
,也是可以获取到DOM的;
也就是说,在ngOnInit函数中可以获取到box,并且改变颜色;
2. angular利用ViewChild获取DOM节点
标题1中利用了原生JS获取DOM节点,其实还可以利用ViewChild获取DOM节点;
利用ViewChild获取myBox节点,并赋值给myBox变量
3. 父组件利用ViewChild调用子组件
举例:在news组件中引入header组件
在父组件news中利用装饰器@ViewChild获取子组件实例;
在父组件中就可以调用子组件中的方法了
在news组件中的ngAfterViewInit()函数中,调用子组件方法
4. 侧边栏弹出与隐藏
侧边栏弹出与隐藏可以用CSS3中的transform;
这里要在主页面的body元素设置:width:100%,overflow-x:hidden;x轴超出部分隐藏
动画效果过渡2秒,transition:all 2s;
5. 父子通信
5.1 父组件给子组件传值@input
这里注意,子组件不仅可以接收父组件传来的变量,也可以接收父组件传来的方法,具体语法和接收变量语法一样
5.2 父组件把自身全部传给子组件
利用[home] = ‘this’,这里的this表示父组件实例
5.3 父组件获取子组件数据
5.3.1 利用@ViewChild
可以利用标题3讲述的@ViewChild获取;
5.3.2 利用@Output
示例:子组件中有一个方法,run
父组件中引入了子组件app-footer,并且利用outer拿到组件的数据,这里outer会触发了父组件中的run方法,$event就是子组件的事件对象
父组件中的run方法,可以打印出子组件传给父组件的数据
6. 非父子组件的通信
6.1 localStorage
6.2 利用服务services
7. 生命周期函数
有父子组件传值时,会触发ngOnChanges()函数;
请求数据或者一些初始化的方法一般放在ngOnInit()函数中;
使用ngIf
就是实现组件挂载和卸载的;
执行顺序:先执行构造函数,再执行ngOnChanges()函数,接着ngOnit()函数
8. 双向数据绑定
需要在app.module.ts中引入FormModule
9. RxJS
RxJS是针对异步数据流编程工具;
目前常见的异步编程方法:
- 回调函数
- 事件监听/发布订阅
- Promise
- Rxjs
9.1 同步方法
- 新建一个服务
- 在app.modules中引入并注入服务
- 在其他组件中引入、声明并使用服务
这时,利用this.require.getData()执行的是同步方法,获取到了服务中的同步方法
9.2 异步方法
服务中的getCallbackData属于异步方法
此时打印出来的是undefined,说明无法获取异步数据;
解决办法:
-
利用回调函数
服务中的getCallbackData
-
利用Promise
-
RxJS处理异步
成功用observer.next(‘传入数据’);
失败用observer.error(‘传入数据’);
9.3 过1秒后撤回之前的操作
-
Promise最终结果是resolve,或者reject,都只能触发一次;在同一个Promise对象上多次调用resolve,会抛出异常;
-
Observable可以不断地触发下一个值
-
过滤器
-
对返回的数据进行处理
-
混用filter和map
-
延迟执行
10. angular中的数据交互
10.1 利用HttpClientModule请求数据
接着利用get请求数据
对于post请求,需要比get请求多引入一个服务(在需要用到的地方引入即可,在module中就不需要再引入了)
10.2 利用Jsonp请求数据
jsonp跨域请求数据
在本地写一个xx方法,在远程执行xxx方法,并将远程获取到的数据传入本地;
11. 封装请求
利用rxjs的模块需要在app.module.ts中引入,并在imports中注入;
利用自己封装的模块,也需要在app.module.ts中引入,并在providers中注入;
之后,在需要用到的地方引入
12. 路由
12.1 基本路由
app-routing.module.ts中写入路由;
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './components.home/home.component';
const routes: Routes = [
{
// 匹配不到路由的时候加载home路由
path: '**', redirectTo: 'home
},
{
path: 'home', component: HomeComponent
},
...
]
在app-module.ts导入路由服务
app.component.html中利用<router-outlet></router-outlet>
进行路由占位;
12.2 路由get传值
路由切换可以用<a>标签
<a routerLink='/home' routerLinkActive="active">首页</a>
<a routerLink='/news' routerLinkActive="active">新闻组件</a>
<a routerLink]="[ '/product' ]" [queryParams]="{aid: key}" routerLinkActive="active">商品</a>
queryParams相当于get传值,地址栏:/product?aid=key
.active {
color: red;
}
想要获取queryParams值,可以这样操作
在某一个组件中
import { ActivatedRoute } from '@angular/router';
export class NewscontentComponent implements OnInit {
constructor(public route: ActivatedRoute) {}
ngOnInit() {
console.log(this.route.queryParams);
this.route.queryParams.subscribe(value => {
console.log(value);
})
}
}
12.3 动态路由
{
path: 'newscontent/:aid', component: NewscontentComponent
}
地址栏:/newscontent/1
<ul>
<li *ngFor="let item of list; let key = index;">
<a routerLink]="[ '/newscontent', key ]" >item</a>
</li>
</ul>
获取传入的aid值
import { ActivatedRoute } from '@angular/router';
export class NewscontentComponent implements OnInit {
constructor(public route: ActivatedRoute) {}
ngOnInit() {
this.route.params.subscribe(value => {
console.log(value); // {aid: 1}
})
}
}
12.4 动态路由的js跳转
<button (click) = "goNewsContent()">跳转</button>
import { Router } from '@angular/router';
export class ProductComponent implements OnInit {
constructor (public router: Router) {}
ngOnInit () {}
goNewsContent () {
// 路由跳转
this.router.navigate(['/newcontent/', '1234'])
}
}
12.5 动态路由js跳转 + get传值
import { Router, NavigationExtras } from '@angular/router';
export class ProductComponent implements OnInit {
constructor (public router: Router) {}
ngOnInit () {}
goNewsContent () {
let navigationExtras: NavigationExtras = {
queryParams: { 'session_id': '123' },
};
// 路由跳转
this.router.navigate(['/newcontent/'], navigationExtras)
}
}
12.6 angular路由嵌套 父子路由
{
path: 'newscontent', component: NewscontentComponent,
children: [
{ path: 'welcome', component: WelcomeComponent},
{ path: 'setting', component: SettingComponent},
]
}
在父组件 newscontent 的html中写上<router-outlet></router-outlet>