初始化angular项目 G:\project\angularui\
i => install == 安装
-S => save == 保存
-D =>devDependencies => 写入devDependencies,发布到生产环境
-g =>global => 全局安装
ng new angularui //样式选择less
cd angularui //进到项目目录
cnpm i //通过cnpm安装依赖
ng serve --open //运行或npm start
在src/app路径下创建四个 Component文件
ng g component pages/home //相当于ng generate component pages/home
ng g component pages/create
ng g component pages/complete
ng g component pages/general/testpages
ng g component theme/asides/app-asideA //产品菜单
ng g component theme/asides/app-asideB //计划菜单
ng g component theme/asides/app-asideC //物流菜单
ng g component theme/asides/app-asideD //制造菜单
ng g component theme/asides/app-asideE //资金菜单
ng g component theme/asides/app-asideF //协作菜单
ng g component theme/asides/app-asideG //查控菜单
ng g component theme/asides/app-asideH //配置菜单
ng g component theme/components/app-aside-header
ng g component theme/components/app-aside-footer
包含以下组件
npm install @clr/icons @clr/ui @clr/angular
npm install rxjs //rxjs
npm install --save redux //redux
npm install @ngrx/core @ngrx/store @ngrx/effects --save-dev //统一引入
//一键引入
npm install rxjs redux @ngrx/core @ngrx/store @ngrx/effects --save-dev
原始项目导入
G:\workspace\uidemo\下的testangui.rar复制到G:\project\angularui解压改名字
cd G:\project\angularui\demo
cnpm install
npm start //运行
webpack官方
npm install axios --save
element官方文档
npm i --save element-angular
在styles.css中引入
@import "~element-angular/theme/index.css";
引入ElModule在app.module.ts中
import { ElModule } from 'element-angular';
// import 模块导入
ElModule.forRoot(),
html使用
<div class="page">
<el-collapse [model]="[]" class="list">
<el-collapse-item *ngFor="let item of menus" label={{item.name}} value={{item.id}}>
<div class="details" *ngFor="let detailsList of item.details">
{{detailsList}}
div>
el-collapse-item>
el-collapse>
div>
导入模块
$ ng new PROJECT_NAME
$ cd PROJECT_NAME
$ ng add ng-zorro-antd
或(以上方式太慢,一般用 cnpm直接在项目中添加)
$ npm install ng-zorro-antd --save
github源码
ng-zorro官方中文文档
手动引入
$ npm install ng-zorro-antd --save
该配置将包含组件库的全部样式,如果只想使用某些组件请查看 使用特定组件样式 配置。
在 angular.json
中引入了
{
"styles": [
"node_modules/ng-zorro-antd/ng-zorro-antd.min.css"
]
}
在 style.css
中引入预构建样式文件
@import "~ng-zorro-antd/ng-zorro-antd.min.css";
在 style.less
中引入 less 样式文件
@import "~ng-zorro-antd/ng-zorro-antd.less";
由于组件之间的样式也存在依赖关系,单独引入多个组件的 CSS 可能导致 CSS 的冗余。
使用特定组件样式时前需要先引入基本样式(所有组件的共用样式)。
在 style.css
中引入预构建样式文件
@import "~ng-zorro-antd/style/index.min.css"; /* 引入基本样式 */
@import "~ng-zorro-antd/button/style/index.min.css"; /* 引入组件样式 */
在 style.less
中引入 less 样式文件
@import "~ng-zorro-antd/style/entry.less"; /* 引入基本样式 */
@import "~ng-zorro-antd/button/style/entry.less"; /* 引入组件样式 */
最后你需要将想要使用的组件模块引入到你的 app.module.ts
文件和特性模块中。
以下面的 NzButtonModule
模块为例,先引入组件模块:
import { NgModule } from '@angular/core';
import { NzButtonModule } from 'ng-zorro-antd/button';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
NzButtonModule
]
})
export class AppModule { }
然后在模板中使用:
<button nz-button nzType="primary">Primarybutton>
控制台
>G:
cd G:\project\angularui
ng new newdemo //(名字任意取,小写),开始新建项目:
//通过key选择一个css样式,scss
//按两下ctrl +c,停止运行
cd newdemo //进入项目目录
cnpm i //(下载package.json里面的依赖包):
ng serve //ng启动
或
npm start //npm启动,vs code中使用,ctrl+` 打开控制台
最后成功打开项目:http://localhost:4200可以直接访问
在根文件夹下的 package.json 文件
这里有一个 “start” 属性,更改这里的值:
"scripts": {
"ng": "ng",
"start": "ng serve --port 4203 --env=dev",
"build": "ng build --env=prod",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},
路由配置
angular官方文档简中
路由跳转
ng generate module app-routing --flat --module=app
/app-routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HeroesComponent } from './heroes/heroes.component';
const routes: Routes = [
{ path: 'heroes', component: HeroesComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
path
: 用来匹配浏览器地址栏中 URL 的字符串。
component
: 导航到该路由时,路由器应该创建的组件。
@NgModule
元数据会初始化路由器,并开始监听浏览器地址的变化。
app.component.html则改为
{{title}}
使用 CLI 添加一个 DashboardComponent
:
ng generate component dashboard
导航到仪表盘app-routing.module.ts
const routes: Routes = [
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
{ path: 'dashboard', component: DashboardComponent },
{ path: 'detail/:id', component: HeroDetailComponent },
{ path: 'heroes', component: HeroesComponent }
];
仪表盘添加dashboard.component.html
{{hero.name}}
更改src/app/heroes/heroes.component.html (list with links)
清除死数据
src/app/heroes/heroes.component.ts (cleaned up)
export class HeroesComponent implements OnInit {
heroes: Hero[];
constructor(private heroService: HeroService) { }
ngOnInit() {
this.getHeroes();
}
getHeroes(): void {
this.heroService.getHeroes()
.subscribe(heroes => this.heroes = heroes);
}
}
获取创建本组件的路由
hero-detail为详情页
从这个路由中提取出 id
通过 HeroService
从服务器上获取具有这个 id
的英雄数据。
src/app/hero-detail/hero-detail.component.ts
import { ActivatedRoute } from '@angular/router';
import { Location } from '@angular/common';
import { HeroService } from '../hero.service';
//构造器中添加
constructor(
private route: ActivatedRoute,
private heroService: HeroService,
private location: Location
) {}
路由参数获取id
src/app/hero-detail/hero-detail.component.ts
ngOnInit(): void {
this.getHero();
}
getHero(): void {
const id = +this.route.snapshot.paramMap.get('id');
this.heroService.getHero(id)
.subscribe(hero => this.hero = hero);
}
添加服务src/app/hero.service.ts (getHero)
getHero(id: number): Observable {
//新添加服务
this.messageService.add(`HeroService: fetched hero id=${id}`);
return of(HEROES.find(hero => hero.id === id));
}
反引号 ( ) 用于定义 JavaScript 的模板字符串字面量,以便嵌入
id`。
添加返回方法src/app/hero-detail/hero-detail.component.ts (goBack)
goBack(): void {
this.location.back();
}
页面src/app/hero-detail/hero-detail.component.html (back button)
app.component.ts下
export class AppComponent {
// title = 'agraui';
}
则在app.component.html绑定
<h1>{{title}} h1>
UpperCasePipe把文本转换成全大写形式。
{{hero.name | uppercase}} Details
src/app下定义Hero.ts
export interface Hero {
id: number;
name: string;
}
则ts中引用为
import { Component, OnInit } from '@angular/core';
import { Hero } from '../hero'; //导入Hero
@Component({
selector: 'app-heroes',
templateUrl: './heroes.component.html',
styleUrls: ['./heroes.component.css']
})
export class HeroesComponent implements OnInit {
hero: Hero = {
id: 1,
name: 'Windstorm'
};
constructor() { }
ngOnInit() {
}
}
则html中
<h2>{{hero.name | uppercase}} Detailsh2>
<div><span>id: span>{{hero.id}}div>
<div><span>name: span>{{hero.name}}div>
表单绑定官方文档
双向绑定
[(ngModel)] 是 Angular 的双向数据绑定语法。
需要在app.module.ts导入包
import { FormsModule } from '@angular/forms'; // <-- NgModel lives here
*ngFor="let hero of heroes"
//"*"不可少,hero循环数据heroes
src/app外定义Hero.ts的Hero对象
// 这里是定义对象
export interface Hero {
id: number;
name: string;
}
src\app\mock-heroes.ts中定义数据
import { Hero } from './hero';
export const HEROES: Hero[] = [
{ id: 1, name: '小羊' },
{ id: 2, name: '小李' },
{ id: 3, name: '小毛' },
{ id: 4, name: '不易' },
{ id: 5, name: '很好' },
{ id: 6, name: '刷卡的那' },
{ id: 7, name: '打啊打' },
{ id: 8, name: '啊发放' },
{ id: 9, name: '发发' },
{ id: 10, name: '发发是' },
];
src\app\heroes\heroes.component.ts中引入数据
import { Hero } from '../hero'; //引入对象
import { HEROES } from '../mock-heroes'; //导入数据源HEROES
export class HeroesComponent implements OnInit {
// public hero = 'Windstorm';
selectedHero: Hero; //通过selectedHero选择Hero
onSelect(hero: Hero): void {
this.selectedHero = hero; //定义点击绑定指向Hero
}
hero: Hero = {
id: 1,
name: 'Windstorm',
};
heroes = HEROES; //指向数据源
constructor() {}
ngOnInit(): void {}
}
(click)="onSelect(hero)"
*ngIf="selectedHero"绑定selectedHero,{{选择的元素写法,名称.id}}
[class.selected]="hero === selectedHero"为css样式绑定
*ngFor="let hero of heroes"循环ts中指向的heroes数据
class="heroes"绑定css样式
[(ngModel)]=“selectedHero.name” 文本选择[(ngModel)]
My Heroes
-
{{hero.id}} {{hero.name}}
{{selectedHero.name | uppercase}}
id: {{selectedHero.id}}
1.app.module.ts中:
import { FormsModule } from "@angular/forms";
imports:{
FormsModule
]
创建hero服务
ng generate service hero
ng generate service services/product/product
hero.service.ts获取数据
//导入
import { Hero } from './hero';
import { HEROES } from './mock-heroes';
export class HeroService {
getHeroes(): Hero[] {
return HEROES; // 返回数据
}
constructor() {}
}
页面的component.ts文件导入服务即可
导入的数据则这样写
heroes: Hero[]; // 使用服务定义为声明
// 构造器传入私有hero服务
constructor(private heroService: HeroService) {}
getHeroes(): void {
this.heroes = this.heroService.getHeroes(); // 从服务获取数据
}
ngOnInit(): void {
this.getHeroes(); // 服务此处调用
}
同步操作
src/app/heroes/heroes.component.ts
this.heroes = this.heroService.getHeroes();
server.ts导入rxjs
import { Observable, of } from 'rxjs';
....
getHeroes(): Observable<Hero[]> {
return of(HEROES);
}
component.ts
getHeroes(): void {
this.heroService.getHeroes()
.subscribe(heroes => this.heroes = heroes);
}
MessageService
ng generate service message/websocketservice
ng g component messages
message.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class MessageService {
messages: string[] = [];
add(message: string) {
this.messages.push(message);
}
clear() {
this.messages = [];
}
}
hero.service.ts导入包
import { MessageService } from './message.service';
constructor(private messageService: MessageService) { }
getHeroes(): Observable<Hero[]> {
this.messageService.add('HeroService: fetched heroes'); //添加消息
return of(HEROES);
}
messages/messages.component.html
<div *ngIf="messageService.messages.length">
<h2>Messagesh2>
<button class="clear"
(click)="messageService.clear()">clearbutton>
<div *ngFor='let message of messageService.messages'> {{message}} div>
div>
*ngIf
只有在有消息时才会显示消息区。
Angular 的事件绑定把按钮的 改动/heroes.component.ts 最后src/app/app.component.html添加展示 HTML ts scss 将 src/app/in-memory-data.service.ts 添加模组src/app/app.module.ts (HttpClientModule import)添加到imports数组中 服务器就绪后,丢弃内存 Web API,应用的请求直接传给服务器。 src/app/hero.service.ts (import HTTP symbols)服务中调用 src/app/hero.service.ts导包 修改实现 src/app/hero-detail/hero-detail.component.ts (save) put添加到服务src/app/hero.service.ts (update) 页面src/app/hero-detail/hero-detail.component.html (save)*ngFor
用来在一系列 click
事件绑定到了 MessageService.clear()
。import { Component, OnInit } from '@angular/core';
import { Hero } from '../hero';
import { HeroService } from '../hero.service';
import { MessageService } from '../message.service'; // 导入包
@Component({
selector: 'app-heroes',
templateUrl: './heroes.component.html',
styleUrls: ['./heroes.component.css']
})
export class HeroesComponent implements OnInit {
selectedHero: Hero;
heroes: Hero[];
// 构造器添加
constructor(private heroService: HeroService, private messageService: MessageService) { }
ngOnInit() {
this.getHeroes();
}
onSelect(hero: Hero): void {
this.selectedHero = hero;
this.messageService.add(`HeroesComponent: Selected hero id=${hero.id}`); // 添加消息
}
getHeroes(): void {
this.heroService.getHeroes()
.subscribe(heroes => this.heroes = heroes);
}
}
<app-messages>app-messages>
案例:
<h2>人员登记系统h2>
<div class="people_list">
<ul>
<li>姓名:<input type="text" id="username" [(ngModel)]="peopleInfo.username" value="form_input" />li>
<li>性别:
<input type="radio" value="1" name="sex" id="sex1" [(ngModel)]="peopleInfo.sex"><label for="sex1">男label>
<input type="radio" value="2" name="sex" id="sex2" [(ngModel)]="peopleInfo.sex"><label for="sex2">女label>
li>
<li>城市:
<select name="city" id="city" [(ngModel)]="peopleInfo.city">
<option [value]="item" *ngFor="let item of peopleInfo.cityList">{{item}}option>
select>
li>
<li>爱好:
<span *ngFor="let item of peopleInfo.hobby;let key=index;">
<input type="checkbox" [id]="'check'+key" [(ngModel)]="item.checked" />
<label [for]="'check'+key">{{item.title}}label>
span>
li>
<li>
备注:
<textarea name="mark" id="mark" cols="30" rows="5" [(ngModel)]="peopleInfo.mark">textarea>
li>
ul>
<button (click)="doSubmit()" class="submit">获取表单的内容button>
<br />
<br />
<br />
<pre>
{{peopleInfo|json}}
pre>
div>
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-form',
templateUrl: './form.component.html',
styleUrls: ['./form.component.scss']
})
export class FormComponent implements OnInit {
public peopleInfo: any = {
username: "",
sex: "1",
cityList: ["北京", "上海", "深圳"],
city: "北京",
hobby: [
{
title: "吃饭",
checked: false
},
{
title: "睡觉",
checked: false
},
{
title: "敲代码",
checked: true
}
],
mark:""
}
constructor() { }
ngOnInit() {
}
doSubmit() {
let usernameDom: any = document.getElementById('username');
console.log(usernameDom.value);
}
}
h2{
text-align: center;
}
.people_list{
// background-color:red;
width: 400px;
margin: 0 auto;
padding: 20px;
border: 1px snow blue;
li{
height: 50px;
line-height: 50px;
.form_input{
width: 300px;
height: 40px;
}
}
.submit{
width: 100px;
height: 30px;
float: right;
margin-top: 120px;
}
}
*表单获取后台数据(nrgx)
使用假数据组件
cnpm install angular-in-memory-web-api --save
创建生成类 (服务ts)
src/app/in-memory-data.service.ts
:ng generate service InMemoryData
in-memory-data.service.ts
改为以下内容:import { Injectable } from '@angular/core';
import { InMemoryDbService } from 'angular-in-memory-web-api';
import { Hero } from './hero';
@Injectable({
providedIn: 'root',
})
export class InMemoryDataService implements InMemoryDbService {
createDb() {
// 假数据来源
const heroes = [
{ id: 1, name: '小羊' },
{ id: 2, name: '小李' },
{ id: 3, name: '小毛' },
{ id: 4, name: '不易' },
{ id: 5, name: '很好' },
{ id: 6, name: '刷卡的那' },
{ id: 7, name: '打啊打' },
{ id: 8, name: '啊发放' },
{ id: 9, name: '发发' },
{ id: 10, name: '发发是' },
];
return {heroes};
}
//重写genId方法,以确保英雄总是有id。
//如果heroes数组为空,
//下面的方法返回初始值(11)。
//如果heroes数组不是空的,下面的方法将返回最高的值
//英雄id + 1。
genId(heroes: Hero[]): number {
return heroes.length > 0 ? Math.max(...heroes.map(hero => hero.id)) + 1 : 11;
}
}
import { HttpClientModule } from '@angular/common/http';
import { HttpClientInMemoryWebApiModule } from 'angular-in-memory-web-api';
import { InMemoryDataService } from './in-memory-data.service';
......
// imports中添加
@NgModule({
imports: [
HttpClientModule,
HttpClientInMemoryWebApiModule.forRoot(
InMemoryDataService, { dataEncapsulation: false }
)
})
in-memory-data.service.ts
文件已代替了 mock-heroes.ts
文件,可删除。请求数据
import { Injectable } from '@angular/core';
import { Hero } from './hero';
import { HEROES } from './mock-heroes';
import { Observable, of } from 'rxjs';
import { MessageService } from './message.service';
// 导入此包
import { HttpClient, HttpHeaders } from '@angular/common/http';
@Injectable({
providedIn: 'root',
})
export class HeroService {
private heroesUrl = 'api/heroes'; // 请求地址url
getHero(id: number): Observable<Hero> {
// 此处获取到 服务
this.messageService.add(`HeroService: fetched hero id=${id}`);
return of(HEROES.find((hero) => hero.id === id));
}
/** GET 请求 */
getHeroes(): Observable<Hero[]> {
return this.http.get<Hero[]>(this.heroesUrl);
}
// 日志
private log(message: string) {
this.messageService.add(`HeroService: ${message}`);
}
constructor(
private http: HttpClient,
private messageService: MessageService
) {}
}
错误处理
import { Injectable } from '@angular/core';
import { Hero } from './hero';
import { HEROES } from './mock-heroes';
import { Observable, of } from 'rxjs';
import { MessageService } from './message.service';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { catchError, map, tap } from 'rxjs/operators';
@Injectable({
providedIn: 'root',
})
export class HeroService {
private heroesUrl = 'api/heroes'; // 请求地址url
getHero(id: number): Observable
save(): void {
this.heroService.updateHero(this.hero)
.subscribe(() => this.goBack());
}
/** PUT方法 */
updateHero(hero: Hero): Observable
*demo展示绑定api插件