ng g component components/header
使用组件
<app-header></app-header>
{{}}
{{title}}
this.h="<h2>这是一个h2 用[innerHTML]来解析h2>"
调试工具看看我的属性
-
{{item}}
-
{{item}} --{{i}}
-
{{item}}
3">这是ngIF 判断是否显示
这是ngIF 判断是否显示
- 已支付
- 订单已经确认
- 已发货
getData(){ /*自定义方法获取数据*/
//获取
alert(this.msg);
}
setData(){
//设置值
this.msg='这是设置的值';
}
keyUpFn(e){
console.log(e)
}
注意引入:在app.module.ts中引入FormsModule
import { FormsModule } from '@angular/forms';
@NgModule({
declarations: [
AppComponent,
HeaderComponent,
FooterComponent,
NewsComponent
],
imports: [
BrowserModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
使用:
{{inputValue}}
[ngClass]:
public flag=false;
public arr = [1, 3, 4, 5, 6];
这是一个div
这是一个div
-
{{item}}
[ngStyle]:
public attr='red';
<div [ngStyle]="{'background-color':'green'}">你好ngStylediv>
<div [ngStyle]="{'background-color':attr}">你好ngStylediv>
public today=new Date();
{{today | date:'yyyy-MM-dd HH:mm:ss' }}
大小写转换
{{str | uppercase}}
//转换成大写
{{str | lowercase}}
//转换成小写
日期格式转换
{{today | date:'yyyy-MM-dd HH:mm:ss' }}
小数位数
{{p | number:'1.2-4'}}
JavaScript 对象序列化
JavaScript 对象序列化
{{ { name: 'semlinker' } | json }}
slice
{{ 'semlinker' | slice:0:3 | uppercase }}
自定义管道
自定义管道的步骤:
使用 @Pipe 装饰器定义 Pipe 的 metadata 信息,如 Pipe 的名称 - 即 name 属性
实现 PipeTransform 接口中定义的 transform 方法
1.1 WelcomePipe 定义
import { Pipe, PipeTransform } from '@angular/core';
[@Pipe](/user/Pipe)({ name: 'welcome' })
export class WelcomePipe implements PipeTransform {
transform(value: string): string {
if(!value) return value;
if(typeof value !== 'string') {
throw new Error('Invalid pipe argument for WelcomePipe');
}
return "Welcome to " + value;
}
}
WelcomePipe 使用
{{ 'semlinker' | welcome }}
{{ 'semlinker' | welcome }}
RepeatPipe 定义
import {Pipe, PipeTransform} from '@angular/core';
[@Pipe](/user/Pipe)({name: 'repeat'})
export class RepeatPipe implements PipeTransform {
transform(value: any, times: number) {
return value.repeat(times);
}
}
RepeatPipe 使用
{{ 'lo' | repeat:3 }}
{{ 'lo' | repeat:3 }}
ng g service my-new-service
创建到指定目录下面
ng g service services/storage
import { StorageService } from './services/storage.service';
@NgModule({
declarations: [
AppComponent,
HeaderComponent,
FooterComponent,
NewsComponent,
TodolistComponent
],
imports: [
BrowserModule,
FormsModule
],
providers:
[StorageService],
bootstrap: [AppComponent]
})
export class AppModule { }
import { StorageService } from '../../services/storage.service';
constructor(private storage: StorageService) {
}
使用
addData(){
// alert(this.username);
this.list.push(this.username);
this.storage.set('todolist',this.list);
}
removerData(key){
console.log(key);
this.list.splice(key,1);
this.storage.set('todolist',this.list);
}
git代码地址:
https://github.com/hufanglei/angular-it-demo
https://github.com/hufanglei/angular-it-demo/tree/02
ngAfterViewInit(){
var boxDom:any=document.getElementById('box');
boxDom.style.color='red';
}
import { Component ,ViewChild,ElementRef} from '@angular/core';
@ViewChild('myattr') myattr: ElementRef;
ngAfterViewInit(){
let attrEl = this.myattr.nativeElement;
}
调用子组件给子组件定义一个名称
<app-footer #footerChild>app-footer>
import引入ViewChild
import { Component, OnInit ,ViewChild} from '@angular/core';
ViewChild 和刚才的子组件关联起来
@ViewChild('footerChild') footer;
4.调用子组件
run(){
this.footer.footerRun();
}
transition.component.html
内容区域
transition.component.ts
export class TransitionComponent implements OnInit {
constructor() { }
ngOnInit() {
}
showAside(){
//原生js获取dom节点
var asideDom:any=document.getElementById('aside');
asideDom.style.transform="translate(0,0)";
}
hideAside(){
//原生js获取dom节点
var asideDom:any=document.getElementById('aside');
asideDom.style.transform="translate(100%,0)";
}
}
transition.component.scss
#aside{
width: 200px;
height: 100%;
position: absolute;
right: 0px;
top:0px;
background: #000;
color:#fff;
transform: translate(100%,0);
transition: all 2s;
}
app.component.html
父组件不仅可以给子组件传递简单的数据,还可把自己的方法以及整个父组件传给子组件
import { Component, OnInit ,Input } from '@angular/core';
export class HeaderComponent implements OnInit {
@Input() msg:string
constructor() { }
ngOnInit() {
}
}
这是头部组件--{{msg}}
父组件
子组件
父组件
子组件
import { Component, OnInit ,Input,Output,EventEmitter} from '@angular/core';
@Output() private outer=new EventEmitter();
/*用EventEmitter 和output 装饰器配合使用指定类型变量*/
sendParent(){
// alert('zhixing');
this.outer.emit('msg from child')
}
//接收子组件传递过来的数据
runParent(msg:string){
alert(msg);
}
import { Component, OnInit ,ViewChild} from '@angular/core';
@ViewChild('footerChild') footer;
run(){
this.footer.footerRun();
}
官方文档:https://www.angular.cn/guide/lifecycle-hooks
生命周期函数通俗的讲就是组件创建、组件更新、组件销毁的时候会触发的一系列的方法。
当Angular 使用构造函数新建一个组件或指令后,就会按下面的顺序在特定时刻调用这些生命周期钩子方法。
钩子 | 用途及时机 |
---|---|
ngOnChanges() |
当 Angular(重新)设置数据绑定输入属性时响应。 该方法接受当前和上一属性值的 SimpleChanges 对象在 ngOnInit() 之前以及所绑定的一个或多个输入属性的值发生变化时都会调用。 |
ngOnInit() |
在 Angular 第一次显示数据绑定和设置指令/组件的输入属性之后,初始化指令/组件。在第一轮 ngOnChanges() 完成之后调用,只调用一次。 |
ngDoCheck() |
检测,并在发生 Angular 无法或不愿意自己检测的变化时作出反应。在每个变更检测周期中,紧跟在 ngOnChanges() 和 ngOnInit() 后面调用。 |
ngAfterContentInit() |
当 Angular 把外部内容投影进组件/指令的视图之后调用。第一次 ngDoCheck() 之后调用,只调用一次。 |
ngAfterContentChecked() |
每当 Angular 完成被投影组件内容的变更检测之后调用。ngAfterContentInit() 和每次 ngDoCheck() 之后调用 |
ngAfterViewInit() |
当 Angular 初始化完组件视图及其子视图之后调用。第一次 ngAfterContentChecked() 之后调用,只调用一次。 |
ngAfterViewChecked() |
每当 Angular 做完组件视图和子视图的变更检测之后调用。ngAfterViewInit() 和每次 ngAfterContentChecked() 之后调用。 |
ngOnDestroy() |
每当 Angular 每次销毁指令/组件之前调用并清扫。 在这儿反订阅可观察对象和分离事件处理器,以防内存泄漏。在 Angular 销毁指令/组件之前调用。 |
案例:
参考手册:https://www.npmjs.com/package/rxjs
中文手册:https://cn.rx.js.org/
RxJS 是ReactiveX 编程理念的JavaScript 版本。ReactiveX 来自微软,它是一种针对异步数据
流的编程。简单来说,它将一切数据,包括HTTP 请求,DOM 事件或者普通数据等包装成流
的形式,然后用强大丰富的操作符对流进行处理,使你能以同步编程的方式处理异步数据,
并组合不同的操作符来轻松优雅的实现你所需要的功能。
RxJS 是一种针对异步数据流编程工具,或者叫响应式扩展编程;可不管如何解释RxJS 其目
标就是异步编程,Angular 引入RxJS 为了就是让异步可控、更简单。
RxJS 里面提供了很多模块。这里我们主要给大家讲RxJS 里面最常用的Observable 和
fromEvent。
目前常见的异步编程的几种方法:
1)、回调函数
2)、事件监听/发布订阅
3)、Promise
4)、Rxjs
Promise 处理异步:
let promise = new Promise(resolve => {
setTimeout(() => {
resolve('---promise timeout---');
}, 2000);
});
promise.then(value => console.log(value));
RxJS 处理异步:
import {Observable} from 'rxjs';
let stream = new Observable(observer => {
setTimeout(() => {
observer.next('observable timeout');
}, 2000);
});
stream.subscribe(value => console.log(value));
从上面列子可以看到RxJS 和Promise 的基本用法非常类似,除了一些关键词不同。Promise里面用的是then() 和resolve(),而RxJS 里面用的是next() 和subscribe()。
Promise 和RxJS 的用法基本相似。其实Rxjs 相比Promise 要强大很多。比如Rxjs 中可以中途撤回、Rxjs 可以发射多个值、Rxjs 提供了多种工具函数等等。
如果我们想让异步里面的方法多次执行,比如下面代码。
这一点Promise 是做不到的,对于Promise 来说,最终结果要么resole(兑现)、要么reject(拒绝),而且都只能触发一次。如果在同一个Promise 对象上多次调用resolve 方法,则会抛异常。而Observable 不一样,它可以不断地触发下一个值,就像next() 这个方法的名字所暗示的那样。
let promise = new Promise(resolve => {
setInterval(() => {
resolve('---promise setInterval---');
}, 2000);
});
promise.then(value => console.log(value));
Rxjs
let stream = new Observable(observer => {
let count = 0;
setInterval(() => {
observer.next(count++);
}, 1000);
});
stream.subscribe(value => console.log("Observable>"+value));
注意:Angular6 以后使用以前的rxjs 方法,必须安装rxjs-compat 模块才可以使用map、filter方法。
angular6 后官方使用的是RXJS6 的新特性,所以官方给出了一个可以暂时延缓我们不需要修改rsjx 代码的办法。
npm install rxjs-compat
import {Observable} from 'rxjs';
import 'rxjs/Rx';
let stream= new Observable(observer => {
let count = 0;
setInterval(() => {
observer.next(count++);
}, 1000);
});
stream.filter(val=>val%2==0)
.subscribe(value => console.log("filter>"+value));
stream
.map(value => {
return value * value
})
.subscribe(value => console.log("map>"+value));
Rxjs 的变化参考文档:http://bbs.itying.com/topic/5bfce189b110d80f905ae545
import {Observable} from 'rxjs';
import {map,filter} from 'rxjs/operators';
let stream= new Observable(observer => {
let count = 0;
setInterval(() => {
observer.next(count++);
}, 1000);
});
stream.pipe(
filter(val=>val%2==0)
)
.subscribe(value => console.log("filter>"+value));
stream.pipe(
filter(val=>val%2==0),
map(value => {
return value * value
})
)
.subscribe(value => console.log("map>"+value));
dom转换成dom流,然后对整个dom流进行处理
import {Observable,fromEvent} from 'rxjs';
import {map,filter,throttleTime} from 'rxjs/operators';
var button = document.querySelector('button');
fromEvent(button, 'click').pipe(
throttleTime(1000)
)
.subscribe(() => console.log(`Clicked`));
Angular5.x 以后get、post 和和服务器交互使用的是HttpClientModule 模块。
1、在app.module.ts 中引入HttpClientModule 并注入
import {HttpClientModule} from '@angular/common/http';
imports: [
BrowserModule,
HttpClientModule
]
import {HttpClient} from "@angular/common/http";
constructor(public http:HttpClient) { }
3、get 请求数据
var api = "http://a.itying.com/api/productlist";
this.http.get(api).subscribe(response => {
console.log(response);
});
Angular5.x 以后get、post 和和服务器交互使用的是HttpClientModule 模块。
1、在app.module.ts 中引入HttpClientModule 并注入
import {HttpClientModule} from '@angular/common/http';
imports: [
BrowserModule,
HttpClientModule
]
2、在用到的地方引入HttpClient、HttpHeaders 并在构造函数声明HttpClient
import {HttpClient,HttpHeaders} from "@angular/common/http";
constructor(public http:HttpClient) { }
3、post 提交数据
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
var api = "http://127.0.0.1:3000/doLogin";
this.http.post(api,{username:'张三',age:'20'},httpOptions).subscribe(response => {
console.log(response);
});
1、在app.module.ts 中引入HttpClientModule、HttpClientJsonpModule 并注入
import {HttpClientModule,HttpClientJsonpModule} from '@angular/common/http';
imports: [
BrowserModule,
HttpClientModule,
HttpClientJsonpModule
]
2、在用到的地方引入HttpClient 并在构造函数声明import
import {HttpClient} from "@angular/common/http";
constructor(public http:HttpClient) { }
3、jsonp 请求数据
var api = "http://a.itying.com/api/productlist";
this.http.jsonp(api,'callback').subscribe(response => {
console.log(response);
});
整个是vue或者reatjs常用的请求方式,angular也可以使用
1、安装axios
cnpm install axios --save
2、用到的地方引入axios
import axios from 'axios';
3、看文档使用
axios.get('/user?ID=12345')
.then(function (response) {
// handle success
console.log(response);
})
.catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});
ng new angualrdemo08 --skip-install
ng g component home
ng g component news
ng g component newscontent
引入组件
import { HomeComponent } from './home/home.component';
import { NewsComponent } from './news/news.component';
import { NewscontentComponent } from './newscontent/newscontent.component';
配置路由
const routes: Routes = [
{path: 'home', component: HomeComponent},
{path: 'news', component: NewsComponent},
{path: 'newscontent/:id', component: NewscontentComponent},
{
path: '',
redirectTo: '/home',
pathMatch: 'full'
}
];
<h1>
<a routerLink="/home">首页a>
<a routerLink="/news">新闻a>
h1>
<router-outlet>router-outlet>
传值
<h1>
<a routerLink="/home">首页a>
<a routerLink="/news">新闻a>
h1>
<router-outlet>router-outlet>
//匹配不到路由的时候加载的组件或者跳转的路由
{
path: '**', /*任意的路由*/
// component:HomeComponent
redirectTo:'home'
}
<h1>
<a routerLink="/home" routerLinkActive="active">首页a>
<a routerLink="/news" routerLinkActive="active">新闻a>
h1>
<h1>
<a [routerLink]="[ '/home' ]" routerLinkActive="active">首页a>
<a [routerLink]="[ '/news' ]" routerLinkActive="active">新闻a>
h1>
.active{
color:red;
}
const routes: Routes = [
{path: 'home', component: HomeComponent},
{path: 'news', component: NewsComponent},
{path: 'newscontent/:id', component: NewscontentComponent},
{
path: '',
redirectTo: '/home',
pathMatch: 'full'
}
];
<a [routerLink]="[ '/newscontent/',aid]">跳转到详情a>
<a routerLink="/newscontent/{{aid}}">跳转到详情a>
import { ActivatedRoute} from '@angular/router';
constructor( private route: ActivatedRoute) {
}
ngOnInit() {
console.log(this.route.params);
this.route.params.subscribe(data=>this.id=data.id);
}
get传值
1、跳转
<li *ngFor="let item of list;let key=index;">
<a [routerLink]="['/newscontent']" [queryParams]="{aid:key}">{{key}}--{{item}}a>
li>
2、接收
import { ActivatedRoute } from '@angular/router';
constructor(public route:ActivatedRoute) { }
this.route.queryParams.subscribe((data)=>{
console.log(data);
})
动态路由
1、配置动态路由
{
path:'newscontent/:aid',component:NewscontentComponent
}
2、跳转
3、接收
import { ActivatedRoute } from '@angular/router';
constructor(public route:ActivatedRoute) { }
this.route.params.subscribe((data)=>{
console.log(data);
})
import { Router } from '@angular/router';
②初的始化
export class HomeComponent implements OnInit {
constructor(private router: Router) {
}
ngOnInit() {
}
goNews(){
// this.router.navigate(['/news', hero.id]);
this.router.navigate(['/news']);
}
}
this.router.navigate(['/news', hero.id]);
import { Router ,NavigationExtras} from '@angular/router';
goNewsContent(){
let navigationExtras: NavigationExtras = {
queryParams: { 'session_id': '123' },
fragment: 'anchor'
};
this.router.navigate(['/news'],navigationExtras);
}
constructor(private route: ActivatedRoute) {
console.log(this.route.queryParams);
}
1)、动态路由
①、引入声明模块
import { Router} from '@angular/router';
constructor(public router:Router) { }
②跳转
this.router.navigate(['/home']);
this.router.navigate(['/newscontent/','1243']);
2)、get传值
①引入声明模块
import { Router} from '@angular/router';
constructor(public router:Router) { }
②跳转
this.router.navigate(['/news'],{
queryParams:{
aid:123
}
});
import { NewsaddComponent } from './components/newsadd/newsadd.component';
import { NewslistComponent } from './components/newslist/newslist.component';
{
path: 'news',
component:NewsComponent,
children: [
{
path:'newslist',
component:NewslistComponent
},
{
path:'newsadd',
component:NewsaddComponent
}
]
}
效果图
代码地址:
https://github.com/hufanglei/angular-it-demo/tree/03
当我们项目比较小的时候可以不用自定义模块。但是当我们项目非常庞大的时候把所有的组
件都挂载到根模块里面不是特别合适。所以这个时候我们就可以自定义模块来组织我们的项
目。并且通过Angular 自定义模块可以实现路由的懒加载。
案例:
创建模块
ng g module module/user --routing
ng g module module/article --routing
ng g module module/product --routing
创建组件:
ng g module module/user --routing
ng g component module/user/components/profile
ng g component module/user/components/order
ng g component module/article
ng g component module/article/components/articlelist
ng g component module/article/components/info
ng g component module/product
ng g component module/product/components/plist
ng g component module/product/components/pinfo
配置懒加载:
import { HomeComponent } from './components/home/home.component';
const routes: Routes = [
{
path:'',component : HomeComponent
},
{
path:'user',loadChildren : './usermodule/usermodule.module#UsermoduleModule'
}
];
源码地址:
https://github.com/hufanglei/angular-it-demo/tree/04
如果图不显示:看我的git地址 https://github.com/hufanglei/angular-it-demo