Angular4 响应式表单应用以及验证
基础的表单类
- AbstractControl是三个具体表单类的抽象基类。 并为它们提供了一些共同的行为和属性,其中有些是可观察对象(Observable)。
- FormControl 用于跟踪一个单独的表单控件的值和有效性状态。它对应于一个HTML表单控件,比如输入框和下拉框。
- FormGroup用于 跟踪一组AbstractControl的实例的值和有效性状态。 该组的属性中包含了它的子控件。 组件中的顶级表单就是一个FormGroup。
- FormArray用于跟踪AbstractControl实例组成的有序数组的值和有效性状态。
添加FormGroup
通常,如果有多个FormControl,我们会希望把它们注册进一个父FormGroup中:
src/app/hero-detail.component.tsimport { Component } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms'; export class HeroDetailComponent2 {heroForm = new FormGroup ({name: new FormControl()});
}
现在我们改完了这个类,该把它映射到模板中了,把hero-detail.component.html改成这样:
src/app/hero-detail.component.html<h2>Hero Detail</h2>
<h3><i>FormControl in a FormGroup</i></h3>
<form [formGroup]="heroForm" novalidate><div class="form-group"><label class="center-block">Name:<input class="form-control" formControlName="name"></label></div>
</form>
- 注意,现在单行输入框位于一个form元素中。<form>元素上的novalidate属性会阻止浏览器使用原生HTML中的表单验证器。
- formGroup是一个响应式表单的指令,它拿到一个现有FormGroup实例,并把它关联到一个HTML元素上。 这种情况下,它关联到的是form元素上的FormGroup实例heroForm。
- 没有父FormGroup的时候,[formControl]="name"也能正常工作,因为该指令可以独立工作,也就是说,不在FormGroup中时它也能用。有了FormGroup,name输入框就需要再添加一个语法formControlName=name,以便让它关联到类中正确的FormControl上。这个语法告诉Angular,查阅父FormGroup(这里是heroForm),然后在这个FormGroup中查阅一个名叫name的FormControl。
表单模型概览
要想知道表单模型是什么样的,请在hero-detail.component.html的form标签紧后面添加如下代码:
src/app/hero-detail.component.htmlcontent_copy
<p>Form value: {{ heroForm.value | json }}</p>
<p>Form status: {{ heroForm.status | json }}</p>
FormBuilder简介
现在,我们遵循下列步骤用FormBuilder来把HeroDetailComponent重构得更加容易读写:
- 明确把heroForm属性的类型声明为FormGroup,稍后我们会初始化它。
- 把FormBuilder注入到构造函数中。
- 添加一个名叫createForm的新方法,它会用FormBuilder来定义heroForm。
- 在构造函数中调用createForm。
src/app/hero-detail.component.tsimport { Component } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';export class HeroDetailComponent3 {heroForm: FormGroup; // <--- heroForm is of type FormGroupconstructor(private fb: FormBuilder) { // <--- inject FormBuilderthis.createForm();}createForm() {this.heroForm = this.fb.group({name: '', // <--- the FormControl called "name"});}
}
FormBuilder.group是一个用来创建FormGroup的工厂方法,它接受一个对象,对象的键和值分别是FormControl的名字和它的定义。 在这个例子中,name控件的初始值是空字符串。
Validators.required 验证器
要想让name这个FormControl是必须的,请把FormGroup中的name属性改为一个数组。第一个条目是name的初始值,第二个是required验证器:Validators.required。
src/app/hero-detail.component.ts this.heroForm = this.fb.group({name: ['', Validators.required ],
});
多级FormGroup
用FormBuilder在这个名叫heroForm的组件中创建一个FormGroup,并把它用作父FormGroup。 再次使用FormBuilder创建一个子级FormGroup,其中包括这些住址控件。把结果赋值给父FormGroup中新的address属性:
src/app/hero-detail.component.ts (excerpt)export class HeroDetailComponent5 {heroForm: FormGroup;states = states;constructor(private fb: FormBuilder) {this.createForm();}createForm() {this.heroForm = this.fb.group({ // <-- the parent FormGroupname: ['', Validators.required ],address: this.fb.group({ // <-- the child FormGroupstreet: '',city: '',state: '',zip: ''}),power: '',sidekick: ''});}
}
在hero-detail.component.html中,把与住址有关的FormControl包裹进一个div中。 往这个div上添加一个formGroupName指令,并且把它绑定到"address"上。 这个address属性是一个FormGroup,它的父FormGroup就是heroForm:
src/app/hero-detail.component.html (address)<div formGroupName="address" class="well well-lg"><h4>Secret Lair</h4><div class="form-group"><label class="center-block">Street:<input class="form-control" formControlName="street"></label></div><div class="form-group"><label class="center-block">City:<input class="form-control" formControlName="city"></label></div><div class="form-group"><label class="center-block">State:<select class="form-control" formControlName="state"><option *ngFor="let state of states" [value]="state">{{state}}</option></select></label></div><div class="form-group"><label class="center-block">Zip Code:<input class="form-control" formControlName="zip"></label></div>
</div>
查看FormControl的属性
可以使用.get()方法来提取表单中一个单独FormControl的状态。 我们可以在组件类中这么做,或者通过往模板中添加下列代码来把它显示在页面中,就添加在{{form.value | json}}插值表达式的紧后面:
src/app/hero-detail.component.html<p>Name value: {{ heroForm.get('name').value }}</p>
<p>Street value: {{ heroForm.get('address.street').value}}</p>
数据模型与表单模型
来自服务器的hero就是数据模型,而FormControl的结构就是表单模型。
组件必须把数据模型中的英雄值复制到表单模型中,这里隐含着两个非常重要的点:
- 开发人员必须理解数据模型是如何映射到表单模型中的属性的
- 户修改时的数据流是从DOM元素流向表单模型的,而不是数据模型,表单控件永远不会修改数据模型
通常只会展现数据模型的一个子集,表单模型的形态越接近数据模型,事情就会越简单,在HeroDetailComponent中,这两个模型是非常接近的,data-model.ts中的Hero定义:
export class Hero {id = 0;name = '';addresses: Address[];
}export class Address {street = '';city = '';state = '';zip = '';
}
组件的FormGroup定义:
src/app/hero-detail.component.ts this.heroForm = this.fb.group({name: ['', Validators.required ],address: this.fb.group({street: '',city: '',state: '',zip: ''}),power: '',sidekick: ''
});
在这些模型中有两点显著的差异:
- Hero有一个id。表单模型中则没有,因为我们通常不会把主键展示给用户
- Hero有一个住址数组。这个表单模型只表示了一个住址
重构一下address这个FormGroup定义,来让它更简洁清晰,代码如下:
src/app/hero-detail.component.ts this.heroForm = this.fb.group({name: ['', Validators.required ],address: this.fb.group(new Address()), // <-- a FormGroup with a new addresspower: '',sidekick: ''
});
使用setValue和patchValue来操纵表单模型
setValue 方法
借助setValue,我们可以立即设置每个表单控件的值,只要把与表单模型的属性精确匹配的数据模型传进去就可以了
src/app/hero-detail.component.ts this.heroForm.setValue({name: this.hero.name,address: this.hero.addresses[0] || new Address()
});
setValue方法会在赋值给任何表单控件之前先检查数据对象的值。
它不会接受一个与FormGroup结构不同或缺少表单组中任何一个控件的数据对象。 这种方式下,如果我们有什么拼写错误或控件嵌套的不正确,它就能返回一些有用的错误信息。 patchValue会默默地失败。
而setValue会捕获错误,并清晰的报告它。
注意,你几乎可以把这个hero用作setValue的参数,因为它的形态与组件的FormGroup结构是非常像的。
我们现在只能显示英雄的第一个住址,不过我们还必须考虑hero完全没有住址的可能性。 下面的例子解释了如何在数据对象参数中对address属性进行有条件的设置:
address: this.hero.addresses[0] || new Address()
patchValue 方法
借助patchValue,我们可以通过提供一个只包含要更新的控件的键值对象来把值赋给FormGroup中的指定控件,这个例子只会设置表单的name控件:
this.heroForm.patchValue({name: this.hero.name
});
借助patchValue,我们可以更灵活地解决数据模型和表单模型之间的差异。 但是和setValue不同,patchValue不会检查缺失的控件值,并且不会抛出有用的错误信息。
什么时候设置表单的模型值(ngOnChanges)
什么时候设置表单的模型值取决于组件何时得到数据模型的值
HeroListComponent组件把英雄的名字显示给用户,当用户点击一个英雄时,列表组件把所选的英雄通过输入属性hero传给HeroDetailComponent:
hero-list.component.html (simplified)<nav><a *ngFor="let hero of heroes | async" (click)="select(hero)">{{hero.name}}</a>
</nav><div *ngIf="selectedHero"><app-hero-detail [hero]="selectedHero"></app-hero-detail>
</div>
这种方式下,每当用户选择一个新英雄时,HeroDetailComponent中的hero值就会发生变化。 我们可以在ngOnChanges钩子中调用setValue,就像例子中所演示的那样, 每当输入属性hero发生变化时,Angular就会调用它。
src/app/hero-detail.component.ts (ngOnchanges)ngOnChanges()this.heroForm.setValue({name: this.hero.name,address: this.hero.addresses[0] || new Address()});
}
重置表单的标识
我们应该在更换英雄的时候重置表单,以便来自前一个英雄的控件值被清除,并且其状态被恢复为pristine(原始)状态。 我们可以在ngOnChanges的顶部调用reset,就像这样:
src/app/hero-detail-7.component.tsthis.heroForm.reset();
reset方法有一个可选的state值,让我们能在重置状态的同时顺便设置控件的值。 在内部实现上,reset会把该参数传给了setValue。 略微重构之后,ngOnChanges会变成这样:
src/app/hero-detail.component.ts (ngOnchanges - revised)ngOnChanges() {this.heroForm.reset({name: this.hero.name,address: this.hero.addresses[0] || new Address()});
}
使用FormArray来表示FormGroup数组
src/app/hero-detail.component.tsthis.heroForm = this.fb.group({name: ['', Validators.required ],secretLairs: this.fb.array([]), // <-- secretLairs as an empty FormArraypower: '',sidekick: ''
});
把表单的控件名从address改为secretLairs让我们遇到了一个重要问题:表单模型与数据模型不再匹配了。
### 初始化FormArray型的secretLairs
下面的setAddresses方法把secretLairs数组替换为一个新的FormArray,使用一组表示英雄地址的FormGroup来进行初始化:
src/app/hero-detail.component.tssetAddresses(addresses: Address[]) {const addressFGs = addresses.map(address => this.fb.group(address));const addressFormArray = this.fb.array(addressFGs);this.heroForm.setControl('secretLairs', addressFormArray);
}
注意,我们使用FormGroup.setControl方法,而不是setValue方法来设置前一个FormArray。 我们所要替换的是控件,而不是控件的值。
### 获取FormArray
使用FormGroup.get方法来获取到FormArray的引用:
get secretLairs(): FormArray {return this.heroForm.get('secretLairs') as FormArray;
};
### 显示FormArray
诀窍在于要知道如何编写*ngFor。主要有三点:
- 在*ngFor的<div>之外套上另一个包装<div>,并且把它的formArrayName指令设为"secretLairs"。 这一步为内部的表单控件建立了一个FormArray型的secretLairs作为上下文,以便重复渲染HTML模板。
- 这些重复条目的数据源是FormArray.controls而不是FormArray本身。 每个控件都是一个FormGroup型的地址对象,与以前的模板HTML所期望的格式完全一样。
- 每个被重复渲染的FormGroup都需要一个独一无二的formGroupName,它必须是FormGroup在这个FormArray中的索引。 我们将复用这个索引,以便为每个地址组合出一个独一无二的标签。
src/app/hero-detail.component.html (excerpt)<div formArrayName="secretLairs" class="well well-lg"><div *ngFor="let address of secretLairs.controls; let i=index" [formGroupName]="i" ><!-- The repeated address template --><h4>Address #{{i + 1}}</h4><div style="margin-left: 1em;"><div class="form-group"><label class="center-block">Street:<input class="form-control" formControlName="street"></label></div><div class="form-group"><label class="center-block">City:<input class="form-control" formControlName="city"></label></div><div class="form-group"><label class="center-block">State:<select class="form-control" formControlName="state"><option *ngFor="let state of states" [value]="state">{{state}}</option></select></label></div><div class="form-group"><label class="center-block">Zip Code:<input class="form-control" formControlName="zip"></label></div></div><br><!-- End of the repeated address template --></div>
</div>
### 把新的address添加到FormArray中
addLair() {this.heroForm.get('secretLairs').push(this.fb.group(new Address()));
}
监视控件的变化
每当用户在父组件HeroListComponent中选取了一个英雄,Angular就会调用一次ngOnChanges。 选取英雄会修改输入属性HeroDetailComponent.hero。
当用户修改英雄的名字或秘密小屋时,Angular并不会调用ngOnChanges。 幸运的是,我们可以通过订阅表单控件的属性之一来了解这些变化,此属性会发出变更通知。
有一些属性,比如valueChanges,可以返回一个RxJS的Observable对象。 要监听控件值的变化,我们并不需要对RxJS的Observable了解更多。
添加下列方法,以监听姓名这个FormControl中值的变化:
src/app/hero-detail.component.ts (logNameChange)nameChangeLog: string[] = [];
logNameChange() {const nameControl = this.heroForm.get('name');nameControl.valueChanges.forEach((value: string) => this.nameChangeLog.push(value));
}
在构造函数中调用它,就在创建表单的代码之后:
src/app/hero-detail-8.component.tsconstructor(private fb: FormBuilder) {this.createForm();this.logNameChange();
}
保存表单数据
### 保存
当用户提交表单时,HeroDetailComponent会把英雄实例的数据模型传给所注入进来的HeroService的一个方法来进行保存:
src/app/hero-detail.component.ts (onSubmit)onSubmit() {this.hero = this.prepareSaveHero();this.heroService.updateHero(this.hero).subscribe(/* error handling */);this.ngOnChanges();
}
原始的hero中有一些保存之前的值,用户的修改仍然是在表单模型中。 所以我们要根据原始英雄(根据hero.id找到它)的值组合出一个新的hero对象,并用prepareSaveHero助手来深层复制变化后的模型值。
src/app/hero-detail.component.ts (prepareSaveHero)prepareSaveHero(): Hero {const formModel = this.heroForm.value;// deep copy of form model lairsconst secretLairsDeepCopy: Address[] = formModel.secretLairs.map((address: Address) => Object.assign({}, address));// return new `Hero` object containing a combination of original hero value(s)// and deep copies of changed form model valuesconst saveHero: Hero = {id: this.hero.id,name: formModel.name as string,// addresses: formModel.secretLairs // <-- bad!addresses: secretLairsDeepCopy};return saveHero;
}
地址的深层复制
我们已经把formModel.secretLairs赋值给了saveHero.addresses(参见注释掉的部分), saveHero.addresses数组中的地址和formModel.secretLairs中的会是同一个对象。 用户随后对小屋所在街道的修改将会改变saveHero中的街道地址。
但prepareSaveHero方法会制作表单模型中的secretLairs对象的复本,因此实际上并没有修改原有对象。
### 丢弃(撤销修改)
丢弃很容易。只要重新执行ngOnChanges方法就可以拆而,它会重新从原始的、未修改过的hero数据模型来构建出表单模型:
src/app/hero-detail.component.ts (revert)revert() { this.ngOnChanges(); }
响应式表单的验证
在响应式表单中,真正的源码都在组件类中。我们不应该通过模板上的属性来添加验证器,而应该在组件类中直接把验证器函数添加到表单控件模型上(FormControl)。然后,一旦控件发生了变化,Angular 就会调用这些函数。
验证器函数
有两种验证器函数:同步验证器和异步验证器。
- 同步验证器函数接受一个控件实例,然后返回一组验证错误或null。我们可以在实例化一个FormControl时把它作为构造函数的第二个参数传进去。
- 异步验证器函数接受一个控件实例,并返回一个承诺(Promise)或可观察对象(Observable),它们稍后会发出一组验证错误或者null。我们可以在实例化一个FormControl时把它作为构造函数的第三个参数传进去。
注意:出于性能方面的考虑,只有在所有同步验证器都通过之后,Angular 才会运行异步验证器。当每一个异步验证器都执行完之后,才会设置这些验证错误。
内置验证器
模板驱动表单中可用的那些属性型验证器(如required、minlength等)对应于Validators类中的同名函数。要想查看内置验证器的全列表,参见 API 参考手册中的Validators部分。
reactive/hero-form-reactive.component.ts (validator functions)ngOnInit(): void {this.heroForm = new FormGroup({'name': new FormControl(this.hero.name, [Validators.required,Validators.minLength(4),forbiddenNameValidator(/bob/i) // <-- Here's how you pass in the custom validator.]),'alterEgo': new FormControl(this.hero.alterEgo),'power': new FormControl(this.hero.power, Validators.required)});
}get name() { return this.heroForm.get('name'); }get power() { return this.heroForm.get('power'); }
注意
- name控件设置了两个内置验证器:Validators.required 和 Validators.minLength(4)。
- 由于这些验证器都是同步验证器,因此我们要把它们作为第二个参数传进去。
- 可以通过把这些函数放进一个数组后传进去,可以支持多重验证器。
- 这个例子添加了一些getter方法。在响应式表单中,我们通常会通过它所属的控件组(FormGroup)的get方法来访问表单控件,但有时候为模板定义一些getter作为简短形式。
reactive/hero-form-reactive.component.html (name with error msg)<input id="name" class="form-control"formControlName="name" required ><div *ngIf="name.invalid && (name.dirty || name.touched)"class="alert alert-danger"><div *ngIf="name.errors.required">Name is required.</div><div *ngIf="name.errors.minlength">Name must be at least 4 characters long.</div><div *ngIf="name.errors.forbiddenName">Name cannot be Bob.</div>
</div>
自定义验证器
shared/forbidden-name.directive.ts (forbiddenNameValidator)/** A hero's name can't match the given regular expression */
export function forbiddenNameValidator(nameRe: RegExp): ValidatorFn {return (control: AbstractControl): {[key: string]: any} => {const forbidden = nameRe.test(control.value);return forbidden ? {'forbiddenName': {value: control.value}} : null;};
}
这个函数实际上是一个工厂,它接受一个用来检测指定名字是否已被禁用的正则表达式,并返回一个验证器函数。
在本例中,禁止的名字是“bob”; 验证器会拒绝任何带有“bob”的英雄名字。 在其他地方,只要配置的正则表达式可以匹配上,它可能拒绝“alice”或者任何其他名字。
forbiddenNameValidator工厂函数返回配置好的验证器函数。 该函数接受一个Angular控制器对象,并在控制器值有效时返回null,或无效时返回验证错误对象。 验证错误对象通常有一个名为验证秘钥(forbiddenName)的属性。其值为一个任意词典,我们可以用来插入错误信息
添加响应式表单
在响应式表单组件中,添加自定义验证器相当简单。你所要做的一切就是直接把这个函数传给 FormControl 。
reactive/hero-form-reactive.component.ts (validator functions)this.heroForm = new FormGroup({'name': new FormControl(this.hero.name, [Validators.required,Validators.minLength(4),forbiddenNameValidator(/bob/i) // <-- Here's how you pass in the custom validator.]),'alterEgo': new FormControl(this.hero.alterEgo),'power': new FormControl(this.hero.power, Validators.required)
});
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
相关文章
- Angular 4中的表单简介:反应形式
您将要创造的 这是“ Angular 4中的表单简介”系列的第二部分。在第一部分中,我们使用模板驱动的方法创建了一个表单。 我们使用了ngModel , ngModelGroup和ngForm等指令来ngModel表单元素。 在本教程中,我们将采用另一种方法来构建表单-反应…...
2024/4/21 4:29:15 - Angular2学习笔记.4、表单相关,双向数据绑定,HeroForm
开始 本次我们将会学会如何用Angular创建表单、two-way data binding(双向数据绑定)、change tracking(检测变化)、validation(验证) 和 error handling(错误处理)等功能以及ngModel、ngControl和ngForm等指令的应用。 这次内容比较长,在最后会给出一个完成的工程…...
2024/4/21 4:29:13 - AngularDart4.0 指南- 表单
2019独角兽企业重金招聘Python工程师标准>>> 表单是商业应用程序的主流。您可以使用表单登录,提交帮助请求,下订单,预订航班,安排会议,并执行无数其他数据录入任务。 在开发表单时,创建一个数据…...
2024/4/21 4:29:12 - 细说 Angular 2+ 的表单(一):模板驱动型表单 (自义验证,实用、赞)
原文出处:https://m.imooc.com/article/details?article_id19902 (应该是《Angular从零到一》作者) 延伸阅读:Angular 4 自定义验证指令 (对“密码一致验证”,做了更详尽的解说,赞)…...
2024/4/21 4:29:11 - angular表单验证笔记篇
一,angular基础指令(笔记见本地新加卷盘) na-mode指令。 <body ng-app"myApp"><!-- 简单部署ngmyApp, --><input ng-model"name"><div class"red">{{name}}</div>…...
2024/4/21 4:29:09 - Angular2 响应式表单验证
响应式表单使用ReactiveFormsModule,而非普通的FormModule,需要在app.module.ts里导入 import { ReactiveFormsModule} from angular/forms;NgModule({declarations: [...],exports:[AppComponent],imports: [BrowserModule,...ReactiveFormsModule],providers: []…...
2024/4/21 4:29:09 - Angular引入百度地图js
第一步:申请百度地图密钥,很简单,去网上随便找教程 第二步:在Angular项目中引入百度地图API文件,在index.html中引入 第三部,创建一个组件 html部分 <div id "map" style"width:100%…...
2024/4/21 4:29:07 - angular js 对象转jquery对象
和jquery一起使用...
2024/5/3 7:40:20 - AngularJS与Angular的区别
指同一事物,版本的区别,叫法不同 Angular2.0之前的版本(1.x)叫做AngularJS 1.x的使用是引入AngularJS的js文件到网页。 2.0之后,就是完全不同了。 Angular2.x与Angular1.x 的区别类似 Java 和 JavaScript 或者说是…...
2024/5/2 16:27:33 - Angular引入自己写的js或者其他
第一,在tsconfig.json设置compilerOptions的allowJs属性为true; 第二,在index.html页面加入要引用的js;如 < script src“assets/js/suibian.js”></ script>; 第三,直接使用方法即可使用。...
2024/5/2 17:15:47 - angular的html引入js,在AngularJS中的文件夹中加载JavaScript和CSS文件
AngularJS不支持你想要的东西,但是你可以看看Grunt或Gulp等构建工具,它们可以让你“构建”你的应用程序.在您的情况下,这些工具可以查找CSS文件并将它们连接成一个文件.这样,如果您添加新模块,则index.html不必更改.我个人使用GulpJS,因为它看起来要快得多.我发现配置更容易&am…...
2024/5/2 18:46:24 - Angular export class AppComponent里定义变量的实现原理
我在Angular项目的app.component.ts使用export class定义了一个Component,在大括号里声明了一个title属性(property): 这个TypeScript转换成对应的JavaScript文件的源代码如下图所示: 在Chrome开发者工具里的webpack文件夹下,可以…...
2024/5/2 17:01:26 - taro1/2及taro3实现原理
taro1/2 taro1/2 是编译类型的小程序跨平台框架。 taro是使用react进行小程序构建的。 React 与小程序之间最大的差异就是他们的模板了,在 React 中,是使用 JSX 来作为组件的模板的,而小程序则是使用字符串模板的。 1、模版转换 taro首…...
2024/4/21 4:29:03 - 简析Vue中的MVVM实现原理
1. MVVM angular - 脏值检测 vue - 数据劫持发布订阅模式(不兼容低版本:因为其依赖于Object.defineProperty) 2. Object.defineProperty() 1.1 概念 Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改…...
2024/4/21 4:29:01 - Angular jasmine spyOn函数的实现原理
例子: 语义:希望service.findFirstFocusable方法被监控,同时其调用之后,返回el变量。 输入参数1:MockkeyboardFocusService输入参数2:字符串findFirstFocusable 这两个参数去调用spyRegistry.spyOn方法。 …...
2024/4/20 19:48:20 - MVVM的实现原理
1.MVVM是什么? 响应式,双向数据绑定,即MVVM。是指数据层(Model)-视图层(View)-数据视图(ViewModel)的响应式框架。它包括: 1.修改View层,Model对…...
2024/5/2 17:42:11 - Angular jasmine单元测试框架里describe的实现原理
源代码:describe函数传入的两个参数:描述信息和箭头函数: 从注释能看出,describe函数的语义:Create a group of specs (often called a suite) getJasmineRequireObj().interface function(jasmine, env) {var jasmi…...
2024/4/24 1:54:35 - 用最简单的代码实现angular的路由守卫
目录简述CanActivate:要求认证CanDeActivate:处理未保存的更改github代码示例简述 ng的文档不得不说写的很好很全,但就是这个很好很全对入门要求很高,我其实只需要有份最简单的代码示例先把功能跑起来就可以了,至于原…...
2024/4/20 10:01:59 - Angular getOrCreateInjectable的实现原理调试
入口:GreetingService是我在Angular项目里定义的abstract service,没有加上Injectable注解: return this._r3Injector.get(token, notFoundValue, injectFlags); this的source为AppModule,records map里已经包含了70个元素&#x…...
2024/4/21 4:28:59 - angular.js实现数据双向通信的原理
angular.js实现数据双向通信的原理 angular的核心特性有:MVVM、模块化、依赖注入、自动化双向数据绑定、语义标签等。 1、AngularJS的scopes对象 AngularJS的scopes对象,是一般的javascript对象,可以在他们上面绑定属性和其他对象,…...
2024/4/21 4:28:59
最新文章
- Git使用及相关问题
总结git中使用的问题 目录 1.git维护文件拷贝后unchanged 1.git维护文件拷贝后unchanged 文件权限不同,文件权限被修改,但内容未改变 命令行中使用git diff: diff --git a/compat/plan9/head b/compat/plan9/head old mode 100755 new mode 100644 主要…...
2024/5/7 15:44:31 - 梯度消失和梯度爆炸的一些处理方法
在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言,在此感激不尽。 权重和梯度的更新公式如下: w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...
2024/5/7 10:36:02 - llama.cpp运行qwen0.5B
编译llama.cp 参考 下载模型 05b模型下载 转化模型 创建虚拟环境 conda create --prefixD:\miniconda3\envs\llamacpp python3.10 conda activate D:\miniconda3\envs\llamacpp安装所需要的包 cd G:\Cpp\llama.cpp-master pip install -r requirements.txt python conver…...
2024/5/7 14:52:49 - 【蓝桥杯】省模拟赛
题目 1.奇数次数2.最小步数3.最大极小值和最小极大值 1.奇数次数 问题描述 给定一个仅包含数字字符的字符串,统计一下这个字符串中出现了多少个值为奇数的数位。 输入格式 输入一行包含一个字符串,仅由数字字符组成。 输出格式 输出一行包含一个整数&am…...
2024/5/7 13:35:55 - 【外汇早评】美通胀数据走低,美元调整
原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...
2024/5/7 5:50:09 - 【原油贵金属周评】原油多头拥挤,价格调整
原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...
2024/5/7 9:45:25 - 【外汇周评】靓丽非农不及疲软通胀影响
原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...
2024/5/4 23:54:56 - 【原油贵金属早评】库存继续增加,油价收跌
原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...
2024/5/7 14:25:14 - 【外汇早评】日本央行会议纪要不改日元强势
原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...
2024/5/4 23:54:56 - 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响
原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...
2024/5/4 23:55:05 - 【外汇早评】美欲与伊朗重谈协议
原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...
2024/5/4 23:54:56 - 【原油贵金属早评】波动率飙升,市场情绪动荡
原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...
2024/5/7 11:36:39 - 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试
原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...
2024/5/4 23:54:56 - 【原油贵金属早评】市场情绪继续恶化,黄金上破
原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...
2024/5/6 1:40:42 - 【外汇早评】美伊僵持,风险情绪继续升温
原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...
2024/5/4 23:54:56 - 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势
原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...
2024/5/4 23:55:17 - 氧生福地 玩美北湖(上)——为时光守候两千年
原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...
2024/5/7 9:26:26 - 氧生福地 玩美北湖(中)——永春梯田里的美与鲜
原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...
2024/5/4 23:54:56 - 氧生福地 玩美北湖(下)——奔跑吧骚年!
原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...
2024/5/4 23:55:06 - 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!
原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...
2024/5/5 8:13:33 - 「发现」铁皮石斛仙草之神奇功效用于医用面膜
原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...
2024/5/4 23:55:16 - 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者
原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...
2024/5/4 23:54:58 - 广州械字号面膜生产厂家OEM/ODM4项须知!
原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...
2024/5/6 21:42:42 - 械字号医用眼膜缓解用眼过度到底有无作用?
原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...
2024/5/4 23:54:56 - 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...
解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...
2022/11/19 21:17:18 - 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。
%读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...
2022/11/19 21:17:16 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...
win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...
2022/11/19 21:17:15 - 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...
有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...
2022/11/19 21:17:14 - win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...
置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...
2022/11/19 21:17:13 - 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...
Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...
2022/11/19 21:17:12 - 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...
有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...
2022/11/19 21:17:11 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...
2022/11/19 21:17:10 - 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...
2022/11/19 21:17:09 - 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?
原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...
2022/11/19 21:17:08 - 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...
关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...
2022/11/19 21:17:05 - 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...
钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...
2022/11/19 21:17:05 - 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...
2022/11/19 21:17:04 - 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...
本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...
2022/11/19 21:17:03 - 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...
许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...
2022/11/19 21:17:02 - 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...
配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...
2022/11/19 21:17:01 - 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...
不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...
2022/11/19 21:17:00 - 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...
当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...
2022/11/19 21:16:59 - 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...
我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢࿰…...
2022/11/19 21:16:58 - 如何在iPhone上关闭“请勿打扰”
Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...
2022/11/19 21:16:57