- Notifications
You must be signed in to change notification settings - Fork 125
Description
安装
基于 Angular Quickstart,使用 Git 克隆 quickstart 项目,安装项目所需依赖并验证环境是否搭建成功
git clone https://github.com/angular/quickstart ng4-quickstart cd quickstart ng4-quickstart npm i npm start定义组件
在app文件夹里面新建components文件夹,在里面新建user.component.ts
import { Component } from '@angular/core'; @Component({ selector: 'sl-user', template: ` <h2>大家好,我是{{name}}</h2> <p>我来自<strong>{{address.province}}</strong>省, <strong>{{address.city}}</strong>市 </p> ` }) export class UserComponent { /*name = 'Semlinker'; address = { province: '广东', city: '广州' };*/ //支持构造函数的形式初始化数据 name: string; address: any; constructor() { this.name = 'Wscats'; this.address = { province: '广东', city: '广州' } } }声明组件
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; //引入刚才新建的user.component文件 import { UserComponent } from './components/user.component'; @NgModule({ imports: [ BrowserModule ], //并在数组中注入UserComponent declarations: [ AppComponent , UserComponent ], bootstrap: [ AppComponent ] }) export class AppModule { }使用组件
在app.component.ts文件里面的template模板中添加<sl-user></sl-user>组件
import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: ` <h1>Hello {{name}} Wscats</h1> <sl-user></sl-user> `, }) export class AppComponent { name = 'Angular'; }接口
定义接口来判断对象的类型
import { Component } from '@angular/core'; //boolean string[] boolean string类型等 //必须写在@Component前面 interface Author { name: string; age: number; } @Component({ selector: 'ws-list', template: ` <ul> <li *ngFor="let p of people;">{{p}}</li> </ul> <p>{{author.name}}<p> ` }) export class UserComponent { author: Author constructor() { this.author = { name: "Corrine", age 666 } this.people = ["wscats", "oaoafly", "corrine"] } }表达式
可以使用{{}}插值语法实现数据绑定
绑定普通文本
import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: `<h1>Hello {{name}}</h1>`, }) export class AppComponent { name = 'Angular'; }绑定对象属性
import { Component } from '@angular/core'; @Component({ selector: 'sl-user', template: ` <h2>大家好,我是{{name}}</h2> <p>我来自<strong>{{address.province}}</strong>省, <strong>{{address.city}}</strong>市 </p> ` }) export class UserComponent { /*name = 'Semlinker'; address = { province: '广东', city: '广州' };*/ name: string; address: any; constructor() { this.name = 'Wscats'; this.address = { province: '广东', city: '广州' } } }管道/过滤器
可以使用Angular内置的json管道,来显示对象信息
@Component({ selector: 'my-app', template: ` ... <p>{{address | json}}</p> `, }) export class AppComponent { name = 'Wscats'; address = { province: '广东', city: '广州' } }常用指令
在Angular实际项目中,最常用的指令是ngIf和ngFor指令
ngFor
语法:
<li *ngFor="let item of items;">...</li>该指令用于基于可迭代对象中的每一项创建相应的模板,它与AngularJS 1.x中的ng-repeat指令的功能是等价的
import { Component } from '@angular/core'; @Component({ selector: 'ws-list', template: ` <ul> <li *ngFor="let p of people">{{p}}</li> </ul> ` }) export class UserComponent { constructor() { this.people = ["wscats","oaoafly","corrine"] } }ngIf
语法:
//接受布尔值 <div *ngIf="condition">...</div>该指令用于根据表达式的值,动态控制模板内容的显示与隐藏,它与AngularJS 1.x中的ng-if指令的功能是等价的
import { Component } from '@angular/core'; @Component({ selector: 'ws-list', template: ` <ul *ngIf = "isShowList"> <li *ngFor="let p of people;"> <div *ngIf = "p.isShow">{{p.name}}</div> </li> </ul> ` }) export class UserComponent { constructor() { this.isShowList = true; this.people = [{ name: "Wscats", isShow: true }, { name: "Oaoafly", isShow: false }, { name: "Corrine", isShow: true }]; } }ngClass
语法
[ngClass]="{'类名':boolean值}"第一个参数为类名称,第二个参数为boolean值,如果为true就添加第一个参数的类,示例组件如下
import { Component } from '@angular/core'; @Component({ selector: 'header-cp', template: ` <h1 [ngClass]="{'red':bool}">header</h1> <button (click)="testClick()">OK</button> `, styles: [` .red{ color: red } `] }) export class HeaderComponent { bool: boolean = true; testClick() { this.bool = !this.bool; } }ngStyle
语法
[ngStyle]="{'css属性名':'css属性值'}"注意驼峰和非驼峰写法均有效果
import { Component } from '@angular/core'; @Component({ selector: 'header-cp', template: ` //驼峰和非驼峰写法均可 <p [ngStyle]="{'backgroundColor':'green'}">header</p> <p [ngStyle]="{'background-color':'green'}">header</p> ` }) export class HeaderComponent {}由于ngShow指令已经移除,所以我们可以用它来实现ngShow指令,就像下面代码一样
[ngStyle]="{'display': bool?'block':'none'}"ngSwitch
语法
[ngSwitch]="变量" *ngSwitchCase="固值1" *ngSwitchCase="固值2" *ngSwitchDefaultngSwitch用于多个条件分支的情况,配合ngSwitchCase和ngSwitchDefault两个指令实现不同的视图切换
<div class="container" [ngSwitch]="myVar"> <div *ngSwitchCase="'A'">Var is A</div> <div *ngSwitchCase="'B'">Var is B</div> <div *ngSwitchCase="'C'">Var is C</div> <div *ngSwitchDefault>Var is something else</div> </div>ngNonBindable
有时候我们需要不要绑定页面的某个部分,使用了ngNonBindable,花括号就会被当做字符串一起显示出来
<div ngNonBindable> {{这里的内容不会被绑定}} </div>innerHTML
输出html结构,比如配合富文本编辑器使用使用,这个指令会非常有用,但也需要注意有可能会遭受XSS攻击
import { Component } from '@angular/core'; //输出html结构必须引入DomSanitizer模块 import { DomSanitizer } from '@angular/platform-browser'; @Component({ selector: 'header-cp', template: ` <div [innerHTML]="html" ></div> `, }) export class HeaderComponent { html: any; constructor(private sanitizer: DomSanitizer) { //如果不用DomSanitizer来转换,会出现警告,并且html结构不会完整显示 this.html = this.sanitizer.bypassSecurityTrustHtml("<p>要进行<span style='color: red'>转换的内容</span>~</p>"); } }ngModel
必须在app.module.ts文件中引入FormsModule 模块,然后就可以在组件中使用ngModel指令
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; // 使用ngModel必须引入FormsModule模块 import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; @NgModule({ // 注入FormsModule imports: [ BrowserModule, FormsModule ], declarations: [ AppComponent ], bootstrap: [ AppComponent ] }) export class AppModule { }组件中就可以使用ngModel进行数据绑定,记得一定要写上name属性,不然不会生效
import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: ` <p>{{num}}</p> <!---双向数据绑定-> <input name="num" type="number" [(ngModel)]="num" /> <!---单向数据绑定-> <input name="num" type="number" [ngModel]="num" /> <button (click)="ok()">ok</button> `, }) export class AppComponent { num = 1; ok(){ this.num++ console.log("ok") } }事件绑定
可以通过(eventName)的语法,实现事件绑定
语法:
<date-picker (dateChanged)="statement()"></date-picker> //等价于 <date-picker on-dateChanged="statement()"></date-picker>下面我们就可以在页面上的按钮中绑定一个on-click事件
import { Component } from '@angular/core'; @Component({ selector: 'ws-event', template: ` <button (click)="toggleSkills()"> {{ showSkills ? "隐藏技能" : "显示技能" }} </button> ` }) export class EventComponent { toggleSkills() { this.showSkills = !this.showSkills; } }Http模块
1.打开app.module.ts文件,从@angular/http模块中导入 Http 类,并在imports数组中注入HttpModule
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { HttpModule } from '@angular/http'; import { AppComponent } from './app.component'; import { UserComponent } from './components/user.component'; import { EventComponent } from './components/event.component'; @NgModule({ imports: [BrowserModule,HttpModule], declarations: [AppComponent, UserComponent, EventComponent], bootstrap: [AppComponent] }) export class AppModule {}2.导入RxJS中的map操作符
3.使用DI方式注入http服务
4.调用http服务的get()方法,设置请求地址并发送HTTP请求
5.调用Response对象的json()方法,把响应体转成JSON对象
6.把请求的结果,赋值给对应的属性
import { Component } from '@angular/core'; import { Http } from '@angular/http'; // (1)步骤1 import 'rxjs/add/operator/map'; // (2)步骤2 导入RxJS中的map操作符 @Component({ selector: 'ws-event', template: ` ` }) export class EventComponent { constructor(private http: Http) {} //(3)步骤3 ngOnInit() { console.log(this); this.http.get(`https://api.github.com/orgs/angular/members?page=1&per_page=5`) // (4) .map(res => res.json()) // (5) .subscribe(data => { if(data) this.members = data; // (6) }); } } }服务
可以再app文件夹下面新建个service文件夹再创建data.service.ts,定义服务文件
export class DataService { getData() { return ['wscat', 'corrine', 'oaoafly']; } }在app.module.ts文件里面的providers数组中注入DataService
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppComponent } from './app.component'; import { UserComponent } from './user.component'; //引入服务 import { DataService } from './service/data.service'; @NgModule({ imports: [ BrowserModule ], declarations: [ AppComponent , UserComponent ], // 全局注入 providers: [ DataService ], bootstrap: [ AppComponent ] }) export class AppModule { }加载data.service.ts文件,引入DataService服务,在constructor里面注入DataService服务,注意是private类型,并把方法命名为dataService在ng的ngOnInit生命周期内即可调用
import { Component } from '@angular/core'; import { DataService } from './service/data.service'; @Component({ selector: 'wscats', template: ` <h1>Hello {{name}}</h1> `, }) export class UserComponent implements OnInit { constructor(private dataService: DataService) { } name = 'Angular'; // 生命周期 ngOnInit() { console.log("父组件ngOninit"); console.log(this.dataService.getData()) setTimeout(()=>{ this.name = "abc" },1000) } }基于服务之间的组件通信
创建data.service.ts服务,并且在主模块中注入,里面的state默认为1
export class DataService { state:number; constructor(){ this.state = 1 } getData() { return ['wscat', 'corrine', 'oaoafly']; } }父组件,触发DataService服务中state的改变
import { Component } from '@angular/core'; import { DataService } from '../../services/data.service'; @Component({ selector: ' wscats-cp', template: ` <!--子组件接受服务的改变--> <test-cp></test-cp> ` }) export class WscatsComponent { constructor(private dataService: DataService) { //父组件利用定时器去改变dataService服务中的的state值 setInterval(() => { this.dataService.state++ console.log(this.dataService) }, 1000) } }子组件,监听DataService中state的变化并进行渲染
import { Component } from '@angular/core'; import { DataService } from '../../services/data.service'; @Component({ selector: 'test-cp', template: ` <!--这里就会观察到dataService的动态改变,从而完成父子之间的通信--> <p>{{dataService.state}}</p> ` }) export class TestComponent { //接受dataService并把它交给TestComponent的私有变量dataService constructor(private dataService: DataService) { } }路由
需要引入@angular/router模块,当然要先在npm包管理中心下载
import { RouterModule } from '@angular/router';路由器包含了多种服务RouterModule和多种指令RouterOutlet、RouterLink、RouterLinkActive
路由告诉路由器,当用户点击链接或者把URL粘贴到浏览器地址栏时,应该显示哪个视图,下面配置的意思为,当URL匹配到/home路由的时候,就在视图RouterOutlet上显示HomeComponent组件
... import { RouterModule } from '@angular/router'; ... // 省略code // 主模块 @NgModule({ // 内置服务 imports: [BrowserModule, RouterModule.forRoot([ { path: 'home', component: HomeComponent } ])], // 注册组件 declarations: [AppComponent, ...], // 自定义服务 providers: [...], // 注根组件 bootstrap: [AppComponent] }) export class AppModule { }我们可以在根组件里,放router-outlet组件,这个相当于我们AngularJS的router-view标签,正如下面代码一样
import { Component } from '@angular/core'; @Component({ selector: 'my-app', template: ` <router-outlet></router-outlet> `, }) export class AppComponent {}当然我们还可以利用routerLink来进行路由的跳转
<a routerLink="/home">Heroes</a>引入样式和脚本
局部
局部样式可以配合styleUrls和styles进行引入
@Component({ selector: 'xpannel', templateUrl: './app.pannel.html', styleUrls: ['./app.pannel.css'], styles: [require("weui")] })全局
全局样式可以在.angular-cli.json文件中引入,注意如果使用cnpm,引入带下划线_,带@符号_weui@1.1.2@weui才是真身,而非weui文件夹,那个是快捷方式,还有文件的路径是基于src文件的相对路径
"styles": [ "styles.css", "../node_modules/_weui@1.1.2@weui/dist/style/weui.css" ],举一反三,全局引入JS也可以在.angular-cli.json文件中的引入
"scripts": [],