创建项目
cd C:\Users\leng_\Desktop\angular
ng new angular-project-name 执行这个命令之后程序会在当前文件夹生成一个名字为 angular-project-name 的 angular 项目
是否设置路由,我们选择 Y
然后通过上下箭头选择一个 CSS 类型的版本, 我们选普通的 CSS
启动项目
cd 到项目目录中
ng serve --open (-- open 是为了自动打开浏览器 http://localhost:4200/)
如果想换端口,在命令行 ctrl + c 中断运行 (Y)
然后 cd 到对应目录 运行 ng serve --port 8888 (路径换成: http://localhost:8888/)
安装 bootstrap
方法1 : UI 框架 引用 bootstrap
https://www.bootcdn.cn/twitter-bootstrap/ 选第一个最新版本的 "bootstrap.min.css bootstrap.min.js"
bootstrap 基于 jquery, 所以也要引入 jquery: 可以用这个 https://code.jquery.com/jquery-latest.js
copy 到 index.html 里
然后打开 app.component.html 里编辑code
BootstrapV4 standard page;
BootstrapV4 standard page English version
方法2: 命令行 cd 到项目目录 npm i bootstrap -S
然后打开 .angular-cli.json 文件 在第一个 styles 节点处添加 bootstrap 的 css "../node_modules/bootstrap/dist/css/bootstrap.min.css"
但是这个方法我没有成功,因为我没有这个文件, 改相似的 angular.json 文件也没有用
创建组件
自动创建:ng g c newComponentName --spec false
- Tips:
- newComponentName 可以是一个路径
- --spec false 不建测试文件
- 我们自己的组件,都应该嵌套在 APP 根级组件之内
在 app 文件夹中新建 我们自己组件的文件夹 - 不缩写的话命令是这个: ng generate component newComponentName
- Angular 程序就是由一个一个小组件组成的, 组件是 Angular 的核心思想
手动创建 了解即可: 先在 app floder 中创建文件夹,然后新建 .css, .ts, .html 文件 (eg: heros.component.css, heros.component.html, heros.component.ts)
创建 component 后 在 app.component.html 直接引用会出错, 解决方案 : app.module.ts 里的 "declarations" 要写所有组件的".ts 文件里的类名"
declarations: [
AppComponent,
HerosComponent
]
并且在头部引用 import { HeaderComponent } from './header/header.component';
组件内容介绍
- 注意大小写: 我自定义的组件名 heros
- heros.component.ts 文件, 里面的 "export class HerosComponent" 就是一个普通的类文件,怎么能让人知道这个文件是 component 内容呢
所以我们要给它加上修饰器
@Component({
selector: 'app-heros',
templateUrl: './heros.component.html',
styleUrls: ['./heros.component.css']
}) - 为了让 修饰器@Component() 好用,要在 .ts 文件头部加上
import { Component, OnInit } from '@angular/core'; -
调用自定义组件:
修饰器@Component() 中的 对象选择器 selector: 'app-heros'
- 这里 "app-heros" 可以根据自己的喜好命名 我们想显示这个组件的时候在 .html code 中 添加这个名字的标签
<app-heroes></app-heroes> - 属性设置: 如果这里的设置加上的大括号 selector: '[app-heros]' 那么调用的时候标签的写法就变为
<div app-heros></div> 将 app-hero 作为了一个属性 - 类的设置: selector: '.app-heros' 调用的时候标签的写法就变为
<div class="app-heros"></div>
- 修饰器@Component() 中的 模板页 templateUrl: './heros.component.html',
- templateUrl: './heros.component.html' 这是一个外部文件的设置
- 内置方法:template: '<p>可以在这里写任何 html 代码, 也可以调用子组件</p> <app-heroes></app-heroes>',
这种 code 如果换行的话 会出现编译错误, 可以把单引号改成反引号 ``, 注意这里用的事 template 不是 templateURL
- 修饰器@Component() 中的 样式文件 styleUrls: ['./heros.component.css']
- styleUrls: ['./heros.component.css'] 这是一个外部文件的设置
- 内置方法:
style:[`
.red {
color: red;
}
`]
这里有换行,所以不能用单引号,仍然要用反引号
- app.module.ts 里的 "declarations" 要写所有组件的".ts 文件里的类名"
declarations: [
AppComponent,
HerosComponent
]
并且在头部引用 import { HeaderComponent } from './header/header.component';
组件嵌套与组件重复
组件建立好了,相互之间可以通过 对象选择器 selector 里的值来回嵌套和 重复使用
<app-heroes></app-heroes>
组件传值总结
- 由上向下是属性绑定,利用 Input 进行接收
- 由下向上是事件绑定, 利用 Output 进行传递,利用EventEmiiter 进行
- 模板中利用 #id 的方式标识元素对象,方便操作获取
- 利用 ViewChild 可以获取元素对象, 并且获取对象相应的属性
- 事件触发可以传递 $event 对象内容
属性及事件绑定
- HTML Elements : 原生属性及事件
eg: button 的 disable 属性 - Diretives : 自定义属性及事件
eg: *ngClass, *ngStyle - Components : 自定义属性及事件
-
自定义属性绑定: 父组件传值给子组件(数据在父组件获取,想要在子组件显示)
以属性的绑定的方式来传值给子组件, 子组件要用 @input() 来声明自定义属性
Demo1 :
父组件Code:
<app-index [title]="父组件要传过去的变量值/变量" [bieming-run]="变量值/变量"></app-index>
子组件Code:
import { Input } from '@angular/core';
@Input() title;
@Input('bieming-run') run; //这里也可以设置别名,让外界看不见子组件里实际的变量名 run
Demo2 :
父组件 recipe-list code, 此时它要把对象做一个循环将数据传递给子组件 recipe item:
<app-recipes-item *ngFor="let recipe of recipes; let i=index" [item]="recipe" [index]="i"></app-recipes-item>
这里的 recipes 是在 父组件里定义的对象数组
recipes: Recipe[] = [
new Recipe(
"name1",
"desc1",
"imagepath1"
),
new Recipe(
"2",
"3",
"2"
)]
子组件 recipe item code
<div class="row" [ngStyle]="{backgroundColor: index%2 === 1? '#e0e0e0':'#eee'}">
<div class="col-4"><a href=""><img [src]="item.imagePath" class="img-fluid img-thumbnail mt-2"></a></div>
<div class="col-8 pt-2">
<p class="mb-0">名字:{{item.name}}</p>
<p>详情:{{item.description}} </p>
</div>
</div>
@Input() item;
@Input() index; -
自定义事件绑定: 子组件主动发送数据给父组件 (数据在子组件获取,想要在父组件显示)
以自定义事件绑定的方式来传值给父组件, 子组件要用 @output() 来声明自定义方法, 用 EventEmitter 将数据传递上来
父组件Code:
// childOuter 即是子组件发送的outer(类似Android中的广播)
过程: 文本框和 button 都是在子组件里, 点击子组件 button 的时候, 子组件调用自身函数 把数据 emit 上来
子组件有两个button 的时候就有两个事件绑定
我们要做的是 点击 子组件 button 的时候只传值给父组件,然后猝发父组件相应的方法
(childOuter)="getFatherData($event)" 这句就是子组件传 childOuter 值给父组件,猝发父组件 getFatherData 方法
引用子组件: <app-index (childOuter)="getFatherData($event)" (othername)="getFatherData2($event)"><app-index>
// ts文件中:
getFatherData(msg:string)
{
console.log(msg);// 接收到的数据
}
//接收到的多参数数据
serverElements = [{name:"11", content:"22"}];
getFatherData2(serverData{serverName:string, serverContent:string})
{
this.serverElements.push({name:serverData.serverName, content:serverData.serverContent});
删除数组的话用的是 splic(0,1)? }
子组件Code:
<button type="button" class="btn btn-primary" (click)="getDate()">得到子组件数据</button>
<button type="button" class="btn btn-primary" (click)="getDate2()">子组件有两个button</button>
import {Output,EventEmitter} from "@angular/core";
我们需要 EventEmitter 将子组件的数值进行向上的传播, 并且需要 @Output() 对我们的数据进行修饰的操作 ( @Output()里可以取别名,和 @input() 一样)
@Output() childOuter: EventEmitter<string> = new EventEmitter<string>();
@Output('othername') childOuter2: EventEmitter<any> = new EventEmitter< {serverName:string,serverContent:string}>();
getDate() {
// 子组件主动发送数据 发动的是 数据 childOuter
this.childOuter.emit("我是子组件的数据"); }
getDate2() {
//子组件一起发送多个数据
this.childOuter2.emit({
serverName = "11",
serverContent = "22"
}) }
父组件主动调用子组件
父组件Code1:
// 引用子组件 <app-index #index></app-index>
// 使用子组件中的方法
<button (click)="index.childRun()">调用index中的方法</button>
父组件Code version2: 也可以在ts文件中调用:
// 引用子组件 html文件
<app-index #index></app-index>
<button (click)="parentClick(index)">调用index中的方法</button>
// ts 文件
parentClick(obj)
{
obj.childRun();
}
ViewChild主动获取数据
import { ViewChild } from '@angular/core';
import { RecipesListComponent } from './recipes-list/recipes-list.component';
@ViewChild("index", {static: false}) index:RecipesListComponent;
// html中引用组件
<app-index #index></app-index>
<button (click)="parentClick()">调用index中的方法</button>
// ts文件中使用子组件的方法和数据
parentChild()
{
this.index.childRun();
}
获取输入框数值的三种方法
- input 输入框,向后台传值, 我们可以用双向数据绑定,但是也可以用 给 input 定义一个 id 的方法来取值 (对象的本地指向)
- 方法一: 对象的本地指向
<input type="" name="" #testInput>
<button (click)="getInputValue(testInput)">test Get value</button>
getInputValue(nameInput:HTMLInputElement)
{console.log(nameInput.value);}
Tips: 形参类型 HTMLInputElement 可以省略 - 方法二: ViewChild主动获取数据
import { ViewChild } from '@angular/core';
import { ElementRef } from '@angular/core';
<input type="" name="" #testInput>
<button (click)="getInputValue()">test Get value</button>
//声明变量: viewChild 引号里的值一般和控件名要一致
@ViewChild("testInput") myTestInput: ElementRef;
getInputValue()
{
console.log(this.myTestInput.nativeElement.value);
// myTestInput 的变量类型一开始不知道的话,就先省略变量类型“ElementRef”, 直接打印 console.log(this.myTestInput) 对象看看它是什么类型的
}