我正在处理此表单并希望在输入时进行验证。当前的行为是我选择输入,键入,当我单击其他站点时,它会显示错误。我认为当我设置控制、有效和脏时发生的错误,但我无法弄清楚。
打字稿
buildForm(): void {
this.userForm = this.fb.group({
'email': ['', [
Validators.required,
Validators.pattern('[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$')
]
],
'password': ['', [
Validators.required,
Validators.minLength(6),
Validators.maxLength(25)
]
],
});
this.userForm.valueChanges.subscribe(data => this.onValueChanged(data));
}
onValueChanged(data?: any) {
if (!this.userForm) { return; }
const form = this.userForm;
for (const field in this.formErrors) {
// clear previous error message (if any)
this.formErrors[field] = '';
const control = form.get(field);
if (control && control.invalid && control.dirty) {
const messages = this.validationMessages[field];
for (const key in control.errors) {
this.formErrors[field] += messages[key] …Run Code Online (Sandbox Code Playgroud) angular-material angular angular-reactive-forms angular-forms
在我的应用程序中,我需要一个可重用的嵌套表单组件,例如Address。我希望自己AddressComponent处理自己的 FormGroup,这样我就不需要从外部传递它。在 Angular 会议(视频、演示)上,Angular Core 团队的一名成员 Kara Erikson 建议实现ControlValueAccessor嵌套表单,使嵌套表单实际上只是一个FormControl.
我还发现我需要实现Validator,以便主表单可以看到我的嵌套表单的有效性。
最后,我创建了嵌套表单需要扩展的 SubForm 类:
export abstract class SubForm implements ControlValueAccessor, Validator {
form: FormGroup;
public onTouched(): void {
}
public writeValue(value: any): void {
if (value) {
this.form.patchValue(value, {emitEvent: false});
this.onTouched();
}
}
public registerOnChange(fn: (x: any) => void): void {
this.form.valueChanges.subscribe(fn);
}
public registerOnTouched(fn: any): void {
this.onTouched = fn;
}
setDisabledState(isDisabled: boolean): void {
isDisabled …Run Code Online (Sandbox Code Playgroud) 我在尝试实现嵌套的角度 FormGroup 时遇到了问题。
我正在使用描述表单输入的特定方案(客户端和服务器之间的接口)。我想创建一个具有某些验证的 FormGroup,并找到使用方案对象初始化 FormGroup 的最简单有效的方法。
方案对象属性本身就是对象,因此我想为其中的每一个创建自己的 FormGroup。此外,包含主 FormGroup 的组件包含应该连接到内部 FromGroups(方案对象的键)的子组件。
例如:
MySchema: {
velocity:
{
speed: number,
direction: number
},
position:
{
x: number,
y: number
}
}
Run Code Online (Sandbox Code Playgroud)
主窗体应该有 2 个内部组件 - 速度组件和位置组件。
每个子组件都应该连接到一个子表单组(速度组件到速度组等等)并显示相关的验证。
主窗体应连接到主 FormGroup。
这是一个小例子,在我们的项目中,架构要大得多,手动编写所有内部元素似乎是错误的。
我希望你能帮助我找到更好的方法。
谢谢。
更新
也许我的问题不够清楚..有没有办法将大对象转换为角度形式组/形式控件?
我的每个表单都包含我从服务器收到的对象,手动在 fb 中编写每个元素似乎是错误的。
再次感谢所有已经回答的人
我正在使用带有 mat 自动完成功能的反应式表单。我在应用程序的其他部分使用了自动完成功能,但我无法弄清楚。我有一个formarray,每次我想在我的情况下添加一个新传感器时都会添加一个输入。自动完成在我的第一个输入中工作正常,但是当我尝试添加更多输入时显示错误:错误:必须在索引处为表单控件提供一个值:1
HTML:
<div class="row">
<div class="input-field col s10">
<div class="form-group">
<div formArrayName="sensors_id">
<div *ngFor="let sensor of addHomeboxPForm.get('sensors_id')['controls']; let i = index">
<br>
<input formControlName="{{i}}" type="text" placeholder="Select Sensor" aria-label="Number" matInput [matAutocomplete]="auto1">
<mat-autocomplete autoActiveFirstOption #auto1="matAutocomplete" [displayWith]="displayWith" >
<mat-option (onSelectionChange)="updateForm($event, [sensor.sensors_id], 'sensors_id')" *ngFor="let sensor of filteredOptionsS | async" [value]="sensor.sensor_serial">
{{sensor.sensor_serial}}
</mat-option>
</mat-autocomplete>
<div class="button-left">
<button *ngIf="addHomeboxPForm.controls.sensors_id.value.length > 1" type="button" class="fa" (click)="onRemoveItem(i)">RemoveSensor</button>
</div>
</div>
</div>
</div>
<div class="input-field col s2">
<button type="button" class="btn" (click)="onAddItem()">AddSensor</button>
</div>
Run Code Online (Sandbox Code Playgroud)
TS:
格式数组: 'sensors_id': this.fb.array([], Validators.required),
updateForm(ev: …Run Code Online (Sandbox Code Playgroud) 我通过注入 NgControl 编写了一个反应式组件,并使用 @Self 装饰器进行装饰。我的问题与此类组件的单元测试有关。请看下面的代码:
免责声明:我已经快速复制了代码并进行了一些内联更改。因此,这可能不是编译器满意的代码。
我的反应组件:
@Component({
selector: 'text-input',
templateUrl: '<input type="text" class="native_input" />'
})
class TextInput implements ControlValueAccessor {
protected constructor(@Self() public controlDir: NgControl) {
this.controlDir.valueAccessor = this;
}
// ...followed by other ControlValueAccessor methods
}
Run Code Online (Sandbox Code Playgroud)
单元测试:
describe('TextInput -', () => {
let fixture: ComponentFixture<TextInputHost>;
let textInput: TextInput;
let inputElement: HTMLInputElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
TextInput, TextInputHost
],
imports: [
FormsModule, ReactiveFormsModule
]
});
}));
beforeEach(fakeAsync(() => {
fixture = getTestBed().createComponent(TextInputHost);
textInput = fixture.componentInstance.textInputComponent;
textInput.writeValue('TestValue');
inputElement …Run Code Online (Sandbox Code Playgroud) unit-testing angular-components angular angular-reactive-forms
我有一个反应式表单,当用户在输入中按下 ESC 键时,我想在表单隐藏之前显示一个“你确定”模式。
一旦显示模态,我就会在控制台中收到以下异常:
ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has
changed after it was checked. Previous value: 'ng-untouched: true'. Current
value: 'ng-untouched: false'.
Run Code Online (Sandbox Code Playgroud)
这是一个显示问题的 stackblitz(焦点输入并按 ESC)
注意:当您聚焦输入,模糊并再次聚焦时,问题不会再次出现ng-untouched变化。
有什么解决方法吗?实现此类功能的推荐方法是什么?
提前致谢!
我有带表单的 Angular 6 应用程序。这是一个例子
export class ExampleComponent implements OnInit {
form: FormGroup;
constructor(private fb: FormBuilder) { }
ngOnInit() {
this.form = new FormGroup({
first: new FormControl(),
last: new FormControl()
});
this.markControlsAsDirty(this.form);
}
markControlsAsDirty(form: FormGroup) {
this.form.get('first').markAsDirty();
this.form.get('last').markAsDirty();
}
}
Run Code Online (Sandbox Code Playgroud)
我不想获得单个控件并标记每个字段。我可以将表单组中的所有控件标记为脏吗?
更新我已经添加了stackblitz 示例来表明之前的两个答案是错误的
如何让 FormBuilder 要求数字?
我正在为纬度和经度编写表单构建器。在这下面,
问题:
如何解决这个问题?
'latitude': [null, [Validators.maxLength(32), Validators.min(-90), Validators.max(90)]],
Run Code Online (Sandbox Code Playgroud)
如果可能,最好在表单中进行验证,而不是输入文本框 type=number,
typescript angular-material angular angular-reactive-forms angular8
我正在创建一个自定义角度组件,当我的 FormControl(反应式表单)无效时,它会显示错误工具提示。但我不知道如何访问自定义组件中的 FormControl 以检查它是否被标记为有效。
我想要完成的
<div [formGroup]="form">
<input formControlName="name" type="text" />
<custom-validation-message formControlName="name">My special error message!</custom-validation-message>
</div>Run Code Online (Sandbox Code Playgroud)
已经遇到的东西
错误错误:没有名称的表单控件的值访问器:'surveyType'
通过使用 NG_VALUE_ACCESSOR 实现 ControlValueAccessor 来修复此问题,即使我不想更改该值。我还添加了一个注入器来访问 NgControl。
import { Component, OnInit, Injector } from '@angular/core';
import { NgControl, ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'custom-validation-message',
templateUrl: './validation-message.component.html',
providers: [{
provide: NG_VALUE_ACCESSOR, multi: true, useExisting: ValidationMessageComponent
}]
})
export class ValidationMessageComponent implements ControlValueAccessor, OnInit {
public formControl: any;
constructor(private injector: Injector) {
super();
}
public ngOnInit(): void {
const model = this.injector.get(NgControl); …Run Code Online (Sandbox Code Playgroud)将鼠标悬停在表中的第一列上时,会出现一个工具提示,单击按钮会打开包含编辑 json 部分的对话框。
我提供了 2 个功能:-
[请从对话框的左侧部分选择一行]
1) 可以编辑 json(在这种情况下,用户单击左侧部分的行,开始编辑 json,并且在不恢复新更改的情况下,用户单击左侧部分下的不同行,然后再次选择先前选择的行原始 json数据被保留)
2) 用户单击左侧部分的行,并开始从输入字段提供输入(出现在“添加为”按钮上方)我开始更新“编辑 Json”部分中的“mTitle”键,因此一旦用户点击另一个行并再次返回到先前选择的行,json 'mTitle' 键不显示原始(旧)值
预期行为
我期待的是一旦用户提供输入,'mTitle' 键应该被更新(这是有效的)但是在 Add As New 按钮被点击或用户点击后,'mTitle' 键应该再次保留其旧值在另一行。(与情况 1 相同的行为)
Stackblitz 链接 https://stackblitz.com/edit/angular-mat-tooltip-v6m2tz?file=app%2Falert-dialog%2Falert-dialog.component.ts
请建议
警报对话框.component.html
<form [formGroup]="jsonform">
<json-input formControlName="json" name="result"></json-input>
</form>
<form [formGroup]="submitJsonNameAndForm" class="">
<mat-form-field [floatLabel]="'never'" class="alertinput">
<input matInput trim type="text" #alertnamefieldRef formControlName="alertnamefield" placeholder="Custom Alert Name"
autocomplete="off" (keyup) = "passingAlerTitle(alertnamefieldRef?.value)">
</mat-form-field>
</form>
Run Code Online (Sandbox Code Playgroud)
警报对话框.component.ts
passingAlerTitle(event){
this.data.data[this.selectedId].conditionals.alert.mTitle = event;
this.jsonform.setValue({
json: this.data.data[this.selectedId].conditionals
});
}
Run Code Online (Sandbox Code Playgroud) angular ×10
typescript ×3
javascript ×2
angular8 ×1
formarray ×1
html ×1
ng-bootstrap ×1
unit-testing ×1