diff --git a/README.md b/README.md index 884141b2..0a492743 100644 --- a/README.md +++ b/README.md @@ -16,19 +16,15 @@ 『技术博客』:www.frankfeekr.cn | 『开源贡献』:⊱ 英雄招募令 | 『微信订阅号』:全栈开发社区
- - -

在颠覆世界的同时,也要好好关照自己。 @@ -447,5 +429,5 @@ Copyright (c) 2021-present, Frank Lam from zero to hero.


+ Value: {{ name.value }} +
+``` + +修改name值可以通过`FormControl` 提供的 `setValue()` 方法 + +```js +updateName() { + this.name.setValue('Tina'); +} +``` + +#### 3.3.9 表单控件分组 + +表单中通常会包含几个相互关联的控件。响应式表单提供了两种把多个相关控件分组到同一个输入表单中的方法 + +要将表单组添加到此组件中,请执行以下步骤。 + +1. 创建一个 `FormGroup` 实例。 +2. 把这个 `FormGroup` 模型关联到视图。 +3. 保存表单数据。 + +**创建一个 FormGroup 实例** + +在组件类中创建一个名叫 `loginForm` 的属性,并设置为 `FormGroup` 的一个新实例。要初始化这个 `FormGroup`,请为构造函数提供一个由控件组成的对象,对象中的每个名字都要和表单控件的名字一一对应 + +```js +import { Component } from '@angular/core'; +import { FormGroup, FormControl } from '@angular/forms'; + +@Component({ + selector: 'app-profile-editor', + templateUrl: './profile-editor.component.html', + styleUrls: ['./profile-editor.component.css'] +}) +export class ProfileEditorComponent { + loginForm = new FormGroup({ + userName: new FormControl(''), + password: new FormControl(''), + }); +} + +//模板渲染 + +``` + + + +#### 3.3.10 表单验证 + + 表单元素添加`required`关键字表示必填,通过绑定`ngModel`的引用可以拿到到当前组件的信息,通过引用获取到验证的信息 + +```jsx +export class AppComponent { + fromData={ + name:'', + password:'' + }; + + subBtnFUn(obj){ + console.log(obj) + } +} + + +``` + +我们还可以通过 **ngModel** 跟踪修改状态与有效性验证,它使用了三个 CSS 类来更新控件,以便反映当前状态。 + +| 状态 | 为 true 时的类 | 为 false 时的类 | +| :--------------- | :------------- | :-------------- | +| 控件已经被访问过 | `ng-touched` | `ng-untouched` | +| 控件值已经变化 | `ng-dirty` | `ng-pristine` | +| 控件值是有效的 | `ng-valid` | `ng-invalid` | + +#### 3.3.11 自定义表单验证 + + 先引入表单的一些内置依赖 + +```js +import { FormGroup, FormBuilder,Validators } from '@angular/forms'; + +//构造函数里注入FormBuilder +constructor(private fb:FormBuilder) { } + +//错误提醒数据 +formErrors = { + 'title': '', + 'content': '' +}; + + +//在组件类的初始化函数里对表单中的元素的校验进行定义,并调用表单的valueChanges方法,检测表单的输入的变化 +ngOnInit():void { + this.taskInfo.isComplete = 1; + this.tasksForm = this.fb.group({ + userName: ['', [Validators.required, + Validators.maxLength(18), + Validators.minLength(6) ] ], + password: ['', [this.passWordVal]], + phone: ['', [Validators.required,this.phoneVal],] + }); + + phoneVal(phone: FormControl): object { + const value = phone.value || ''; + if(!value) return {desc:'请输入手机号'} + const valid = /[0-9]{11}/.test(value); + return valid ? {} :{desc:'联系电话必须是11位数字'} + } + passWordVal(password:FormControl):object{ + const value = password.value || ''; + const valid = value.match(/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$/); + return valid ? {} : {passwordValidator: {desc:'密码至少包含 数字和英文,长度6-20'}} + } +} +``` + +#### 3.3.12 管道 + + 管道的作用就是传输。不同的管道具有不同的作用。(其实就是处理数据) + +`angular`中自带的`pipe`函数 + +| 管道 | 功能 | +| ------------- | ------------------------------------------------------------ | +| DatePipe | 日期管道,格式化日期 | +| JsonPipe | 将输入数据对象经过JSON.stringify()方法转换后输出对象的字符串 | +| UpperCasePipe | 将文本所有小写字母转换成大写字母 | +| LowerCasePipe | 将文本所有大写字母转换成小写字母 | +| DecimalPipe | 将数值按照特定的格式显示文本 | +| CurrentcyPipe | 将数值进行货币格式化处理 | +| SlicePipe | 将数组或者字符串裁剪成新子集 | +| PercentPipe | 将数值转百分比格式 | + +`pipe`用法 + +- {{ 输入数据 | 管道 : 管道参数}} (其中‘|’是管道操作符) + +- 链式管道 {{ 输入数据 | date | uppercase}} + +- 管道流通方向自左向右,逐层执行 + + 使用脚手架命令:**ng g p test** + + ```js + import { Pipe, PipeTransform } from '@angular/core'; + + @Pipe({ + name: 'testTitle' + }) + export class TestPipe implements PipeTransform { + + transform(value: unknown, ...args: unknown[]): unknown { + console.log(value) + return 'title'; + } + } + + +{{ 'Angular' | testTitle }}
+ + ``` + + + +### 3.4 服务 + + angular中,把从组件内抽离出来的代码叫服务,服务的本质就是函数 + + 官方认为组件不应该直接获取或保存数据, 它们应该聚焦于展示数据,而把数据访问的职责委托给某个服务。而服务就充当着数据访问,逻辑处理的功能。把组件和服务区分开,以提高模块性和复用性。通过把组件中和视图有关的功能与其他类型的处理分离开,可以让组件类更加精简、高效。 + +使用命令ng g s xxx创建一个服务,通过**@Injectable()**装饰器标识服务。 + +```js +//导入Injectable装饰器 +import { Injectable } from '@angular/core'; +//使用Injectable装饰器声明服务 +@Injectable({ + //作用域设定,'root'表示默认注入,注入到AppModule里 + providedIn: 'root', +}) +export class TestService { +} + +``` + +组件中如何使用服务呢,必须将服务依赖注入系统、组件或者模块,才能够使用服务。我们可以用**注册提供商**和**根注入器**实现**。** + + 该服务本身是 CLI 创建的一个类,并且加上了 `@Injectable()` 装饰器。默认情况下,该装饰器是用 `providedIn` 属性进行配置的,它会为该服务创建一个提供商。 + + + +### 3.5 依赖注入 + + 在这个例子中,`providedIn: 'root'` 指定 Angular 应该在根注入器中提供该服务,从而实现**根注入器**将服务注入,它就在整个应用程序中可用了**。** + +**providedIn**: + + 'root' :注入到AppModule,提供该服务,所有子组件都可以使用(推荐) + + null : 不设定服务作用域(不推荐) + + 组件名:只作用于该组件(懒加载模式) + +```js + +import { Injectable } from '@angular/core'; + +@Injectable({ + providedIn: 'root', +}) +export class TestService { +} + + +import { Component, OnInit } from '@angular/core'; +import {HeroService} from '../hero.service' + +@Component({ + selector: 'app-test', + templateUrl: './test.component.html', + styleUrls: ['./test.component.scss'], +}) +export class TestComponent implements OnInit { + + constructor(private heroService:HeroService) { } + + ngOnInit(): void { + console.log(this.heroService.getHeroList()) + } +} +``` + + 也可以使用 `@Component` 或 `@Directive` 内部的 `providers: []`,为特定的组件子树提供服务,这也将导致创建多个服务实例(每个组件使用一个服务实例) + +```js + +import { Injectable } from '@angular/core'; + +@Injectable({ + providedIn: 'root', +}) +export class TestService { +} + + +import { Component, OnInit } from '@angular/core'; +import {HeroService} from '../hero.service' + +@Component({ + selector: 'app-test', + templateUrl: './test.component.html', + styleUrls: ['./test.component.scss'], + providers: [HeroService] +}) +export class TestComponent implements OnInit { + + constructor(private heroService:HeroService) { } + + ngOnInit(): void { + console.log(this.heroService.getHeroList()) + } +} +``` + + + +### 3.6 路由 + + 路由就是连接组件的筋络,它也是树形结构的.有了它,就可以在angular中实现路径的导航模式 + +可以把路由看成是一组规则,它决定了url的变化对应着哪一种状态,具体表现就是不同视图的切换 + +在angular中,路由是非常重要的组成部分, 组件的实例化与销毁,模块的加载,组件的某些生命周期钩子的发起,都是与它有关 + +#### 3.6.1 路由基本使用 + +**路由器**是一个调度中心,它是一套规则的列表,能够查询当前URL对应的规则,并呈现出相应的视图. + +**路由**是列表里面的一个规则,即路由定义,它有很多功能字段: + +- **path**字段,表示该路由中的URL路径部分 +- **Component**字段,表示与该路由相关联的组件 + +每个带路由的Angular应用都有一个路由器服务的单例对象,通过路由定义的列表进行配置后使用。 + +```js +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; +import {HomeComponent} from './home/home.component' + +const routes: Routes = [ + {path:'home',component:HomeComponent} +]; + +@NgModule({ + imports: [RouterModule.forRoot(routes)], + exports: [RouterModule] +}) +export class AppRoutingModule { } + +``` + +```jsx +//路由导航 +home + hello + +//组件渲染输出 +
