Agnular 基础

1. 概述

Google开发的,单页应用,重量级的框架。内部集成了大量开箱即用的功能模块,应用程序整洁更易于维护。

2. 架构

架构图

1. 模块

NgModule 是一组相关功能的集合,专注于某个应用领域,可以将组件和一组相关代码关联起来。
NgModule 可以从其它 NgModule 中导入功能,前提是目标 NgModule 导出了该功能。
NgModule 是由 NgModule 装饰器函数装饰的类。

	import { BrowserModule } from '@angular/platform-browser';
	import { NgModule } from '@angular/core';
	@NgModule({
		imports: [
			BrowserModule
		]
	})
	export class AppModule { }

2. 组件

组件用来描述用户界面,它由html(组件模板),css(组件样式),js(组件类)组成,可以是一个文件,也可以是三个文件。
组件类是由 Component 装饰器函数装饰的类。

	import { Component } from "@angular/core"
	@Component({
		selector: "app-root",
		templateUrl: "./app.component.html",
		styleUrls: ["./app.component.css"]
	})
	export class AppComponent {
	title = "angular-test"
}

NgModule 为组件提供了编译的上下文环境。

import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
@NgModule({
	declarations: [
		AppComponent
	],
	bootstrap: [AppComponent]
})
export class AppModule { }

3. 服务

服务用于放置和特定组件无关并希望跨组件共享的数据或逻辑。
服务出现的目的在于解耦组件类中的代码,是组件类中的代码干净整洁。
服务是由 Injectable 装饰器装饰的类。

import { Injectable } from '@angular/core';
@Injectable({})
export class AppService { }

不要在组件类中通过 new 的方式创建服务实例对象
在组件中获取服务实例对象要结合 TypeScript 类型,写法如下:

import { AppService } from "./AppService"
export class AppComponent {
	constructor (
		private appService: AppService
	) {}
}

3. 快速开始

1. 创建应用

1. 安装 angular-cli:npm install @angular/cli -g

2. 创建应用: ng new angular-test --minimal --inlineTemplate false

1. --skipGit=true // 不会初始化git仓库
2. --minimal=true // 精简模式,删除测试文件,合并html,ts,css文件
3. --skip-install // 跳过自动安装项目依赖
4. --style=css
5. --routing=false
6. --inlineTemplate false // 分离html文件和ts文件
7. --inlineStyle true // 组件类文件和组件样式文件合并为一个文件
8. --prefix // 修改默认文件名前缀

3. 运行应用: ng serve

1. --open=true 应用构建完成后在浏览器中运行
2. --hmr=true 开启热更新
3. hmrWarning=false 禁用热更新警告
4. --port 更改应用运行端口

4. 访问应用: localhost:4200

2. 默认代码解析

1. main.ts

	// enableProdMode 方法调用后将会开启生产模式
	import { enableProdMode } from "@angular/core"
	// Angular 应用程序的启动在不同的平台上是不一样的
	// 在浏览器中启动时需要用到 platformBrowserDynamic 方法, 该方法返回平台实例对象
	import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"
	// 引入根模块 用于启动应用程序
	import { AppModule } from "./app/app.module"
	// 引入环境变量对象 { production: false }
	import { environment } from "./environments/environment"
	// 如果当前为生产环境
	if (environment.production) {
		// 开启生产模式
		enableProdMode()
	}
	// 启动应用程序
	platformBrowserDynamic()
		.bootstrapModule(AppModule)
		.catch(err => console.error(err))

2. environment.ts

// 在执行 `ng build --prod` 时, environment.prod.ts 文件会替换 environment.ts 文件
// 该项配置可以在 angular.json 文件中找到, projects -> angular-test -> architect ->
configurations -> production -> fileReplacements
	export const environment = {
production: false
}

3. environment.prod.ts

export const environment = {
	production: true
}

4. app.module.ts

// BrowserModule 提供了启动和运行浏览器应用所必需的服务
// CommonModule 提供各种服务和指令, 例如 ngIf 和 ngFor, 与平台无关
// BrowserModule 导入了 CommonModule, 又重新导出了 CommonModule, 使其所有指令都可用于导
入 BrowserModule 的任何模块
import { BrowserModule } from "@angular/platform-browser"
// NgModule: Angular 模块装饰器
import { NgModule } from "@angular/core"
// 根组件
import { AppComponent } from "./app.component"
// 调用 NgModule 装饰器, 告诉 Angular 当前类表示的是 Angular 模块
@NgModule({
	// 声明当前模块拥有哪些组件
	declarations: [AppComponent],
	// 声明当前模块依赖了哪些其他模块
	imports: [BrowserModule],
	// 声明服务的作用域, 数组中接收服务类, 表示该服务只能在当前模块的组件中使用
	providers: [],
	// 可引导组件, Angular 会在引导过程中把它加载到 DOM 中
	bootstrap: [AppComponent]
})
export class AppModule {}

5 app.component.ts

import { Component } from "@angular/core"
@Component({
	// 指定组件的使用方式, 当前为标记形式
	// app-home => <app-home></app-home>
	// [app-home] => <div app-home></div>
	// .app-home => <div class="app-home"></div>
	selector: "app-root",
	// 关联组件模板文件
	// templateUrl:'组件模板文件路径'
	// template:`组件模板字符串`
	templateUrl: "./app.component.html",
	// 关联组件样式文件
	// styleUrls : ['组件样式文件路径']
	// styles : [`组件样式`]
	styleUrls: ["./app.component.css"]
})
export class AppComponent {}

3. 共享模块

共享模块当中放置的是 Angular 应用中模块级别的需要共享的组件或逻辑。

  1. 创建共享模块: ng g m shared
  2. 创建共享组件: ng g c shared/components/Layout
  3. 在共享模块中导出共享组件
@NgModule({
declarations: [LayoutComponent],
	exports: [LayoutComponent]
})
export class SharedModule {}
  1. 在根模块中导入共享模块
@NgModule({
	declarations: [AppComponent],
	imports: [SharedModule],
	bootstrap: [AppComponent]
})
export class AppModule {}
  1. 在根组件中使用 Layout 组件
@Component({
	selector: "app-root",
	template: `
		<div>App works</div>
		<app-layout></app-layout>
	`,
	styles: []
})
export class AppComponent { }

4. 组件模板

1. 数据绑定

数据绑定就是将组件类中的数据显示在组件模板中,当组件类中的数据发生变化时会自动被同步到组件
模板中(数据驱动 DOM )。
在 Angular 中使用插值表达式进行数据绑定,即 {{ }} 大胡子语法。

<h2>{{message}}</h2>
<h2>{{getInfo()}}</h2>
<h2>{{a == b ? '相等': '不等'}}</h2>
<h2>{{'Hello Angular'}}</h2>
<p [innerHTML]="htmlSnippet"></p> <!-- 对数据中的代码进行转义 -->

2. 属性绑定

1. 普通属性

// 1. 使用 [属性名称] 为元素绑定 DOM 对象属性。
<img [src]="imgUrl"/>
// 2. 使用 [attr.属性名称] 为元素绑定 HTML 标记属性
<td [attr.colspan]="colSpan"></td>

大多数情况下,DOM 对象属性和 HTML 标记属性是对应的关系

2. class 属性

<button class="btn btn-primary" [class.active]="isActive">按钮</button>
<div [ngClass]="{'active': true, 'error': true}"></div>

3. style 属性

<button [style.backgroundColor]="isActive ? 'blue': 'red'">按钮</button>
<button [ngStyle]="{'backgroundColor': 'red'}">按钮</button>

3. 事件绑定

<button (click)="onSave($event)">按钮</button>
<!-- 当按下回车键抬起的时候执行函数 -->
<input type="text" (keyup.enter)="onKeyUp()"/>

export class AppComponent {
	title = "test"
	onSave(event: Event) {
		// this 指向组件类的实例对象
		this.title // "test"
	}
}

4. 获取原生 DOM 对象

1. 在组件模板中获取

<input type="text" (keyup.enter)="onKeyUp(username.value)" #username/>

2. 在组件类中获取

  • 使用 ViewChild 装饰器获取一个元素
<p #paragraph>home works!</p>
import { AfterViewInit, ElementRef, ViewChild } from "@angular/core"
export class HomeComponent implements AfterViewInit {
	@ViewChild("paragraph") paragraph: ElementRef<HTMLParagraphElement> | undefined
	ngAfterViewInit() {
		console.log(this.paragraph?.nativeElement)
	}
}
  • 使用 ViewChildren 获取一组元素
<ul>
	<li #items>a</li>
	<li #items>b</li>
	<li #items>c</li>
</ul>
import { AfterViewInit, QueryList, ViewChildren } from "@angular/core"
@Component({
	selector: "app-home",
	templateUrl: "./home.component.html",
	styles: []
})
export class HomeComponent implements AfterViewInit {
	@ViewChildren("items") items: QueryList<HTMLLIElement> | undefined
	ngAfterViewInit() {
		console.log(this.items?.toArray())
	}
}

5. 双向数据绑定

  • 依赖 @angular/forms 中 FormsModule 模块
import { FormsModule } from "@angular/forms"
@NgModule({
	imports: [FormsModule],
})
export class AppModule {}
<input type="text" [(ngModel)]="username" />
<button (click)="change()">在组件类中更改 username</button>
<div>username: {{ username }}</div>
export class AppComponent {
	username: string = ""
	change() {
		this.username = "hello Angular"
	}
}

6. 内容投影(vue中的插槽)

  • 投影多个:
<!-- app.component.html -->
<bootstrap-panel>
	<div class="heading">
		Heading
	</div>
	<div class="body">
		Body
	</div>
</bootstrap-panel>

<!-- panel.component.html -->
<div class="panel panel-default">
	<div class="panel-heading">
		<ng-content select=".heading"></ng-content>
	</div>
	<div class="panel-body">
		<ng-content select=".body"></ng-content>
	</div>
</div>
  • 投影一个:
<!-- app.component.html -->
<bootstrap-panel>
	<ng-container class="heading">
		Heading
	</ng-container>
	<ng-container class="body">
		Body
	</ng-container>
</bootstrap-panel>

7. 数据绑定容错处理

<span>{{ task.person?.name }}</span>

8. 全局样式

/* 第一种方式 在 styles.css 文件中 */
@import "~bootstrap/dist/css/bootstrap.css";
/* ~ 相对node_modules文件夹 */
<!-- 第二种方式 在 index.html 文件中 -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" rel="stylesheet" />
// 第三种方式 在 angular.json 文件中
"styles": [
	"./node_modules/bootstrap/dist/css/bootstrap.min.css",
	"src/styles.css"
]

9. 视图封装

Component 的装饰器提供了 encapsulation 选项,可用来控制如何基于每个组件应用视图封装。

5. 指令 Directive

指令是 Angular 提供的操作 DOM 的途径。指令分为属性指令和结构指令。
属性指令:修改现有元素的外观或行为,使用 [] 包裹。
结构指令:增加、删除 DOM 节点以修改布局,使用*作为指令前缀

1. 内置指令

1. *ngIf

<div *ngIf="data.length == 0">没有更多数据</div>
<div *ngIf="data.length > 0; then dataList else noData"></div>
<ng-template #dataList>课程列表</ng-template>
<ng-template #noData>没有更多数据</ng-template>

2. [hidden]

<div [hidden]="data.length == 0">课程列表</div>
<div [hidden]="data.length > 0">没有更多数据</div>

3. *ngFor

<li
*ngFor="
let item of list;
let i = index;
let isEven = even;
let isOdd = odd;
let isFirst = first;
let isLast = last;
"
>
</li>
<li *ngFor="let item of list; trackBy: identify"></li>

// 方法中获取相关参数
identify(index, item){
	return item.id;
}

2. 自定义指令

需求:为元素设置默认背景颜色,鼠标移入时的背景颜色以及移出时的背景颜色。

<div [appHover]="{ bgColor: 'skyblue' }">Hello Angular</div>
import { AfterViewInit, Directive, ElementRef, HostListener, Input } from
"@angular/core"
// 接收参的数类型
interface Options {
	bgColor?: string
}
@Directive({
	selector: "[appHover]"
})
export class HoverDirective implements AfterViewInit {
	// 接收参数
	@Input("appHover") appHover: Options = {}
	// 要操作的 DOM 节点
	element: HTMLElement
	// 获取要操作的 DOM 节点
	constructor(private elementRef: ElementRef) {
		this.element = this.elementRef.nativeElement
	}
	// 组件模板初始完成后设置元素的背景颜色
	ngAfterViewInit() {
		this.element.style.backgroundColor = this.appHover.bgColor || "skyblue"
	}
	// 为元素添加鼠标移入事件
	@HostListener("mouseenter") enter() {
		this.element.style.backgroundColor = "pink"
	}
	// 为元素添加鼠标移出事件
	@HostListener("mouseleave") leave() {
		this.element.style.backgroundColor = "skyblue"
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值