Angular 19 사용자 정의 폼 컨트롤
개발 자가 특정한 폼 컨트롤 을 필요 로 할 때 기본 으로 제공 하 는 폼 컨트롤 과 비슷 한 컨트롤 을 폼 컨트롤 로 개발 해 야 합 니 다.사용자 정의 폼 컨트롤 은 모델 과 보기 간 의 데이터 가 어떻게 상호작용 을 하 는 지 고려 해 야 합 니 다.
2 공식 문서->클릭 하여 가기
Angular 는 개발 자 에 게 ControlValueAccessor 인 터 페 이 스 를 제공 하여 개발 자 에 게 사용자 정의 폼 컨트롤 을 구축 하도록 보조 합 니 다.개발 자 는 사용자 정의 폼 컨트롤 류 에서 ControlValueAccessor 인터페이스 에서 의 방법 만 실현 하면 모델 과 보기 간 의 데이터 상호작용 을 실현 할 수 있 습 니 다.
interface ControlValueAccessor {
writeValue(obj: any): void
registerOnChange(fn: any): void
registerOnTouched(fn: any): void
setDisabledState(isDisabled: boolean)?: void
}
2.1 writeValue
writeValue(obj: any): void
이 방법 은 사용자 정의 폼 컨트롤 에 값 을 기록 하 는 데 사 용 됩 니 다.이 매개 변수 값(obj)은 이 사용자 정의 폼 컨트롤 을 사용 하 는 구성 요소 가 템 플 릿 폼 이나 응답 식 폼 의 데이터 바 인 딩 을 통 해 전 달 됩 니 다.
사용자 정의 폼 컨트롤 클래스 에서 이 값(obj)을 구성원 변수 에 할당 하면 됩 니 다.사용자 정의 폼 컨트롤 의 보 기 는 속성 바 인 딩 을 통 해 이 값 을 표시 합 니 다.
2.2 registerOnChange
registerOnChange(fn: any): void
사용자 정의 폼 컨트롤 의 데이터 가 변 할 때 registerOnChange 방법 이 실 행 됩 니 다.이 측은 사용자 정의 폼 컨트롤 데이터 의 변 화 를 어떻게 처리 하 는 지 에 사 용 됩 니 다.registerOnChange 방법 으로 받 은 매개 변수(fn)는 사실 하나의 방법 으로 변 화 된 데 이 터 를 처리 하 는 것 을 책임 집 니 다.
사용자 정의 컨트롤 데이터 가 변 할 때 fn 실행 방법 을 자동 으로 호출 합 니 다.그러나 일반적인 방법 은 propagate Change 를 사용 하여 사용자 정의 방법 이 fn 을 가리 키 도록 하 는 것 입 니 다.그러면 데이터 가 변 할 때 propagate Change 를 사용 하면 변 화 된 데 이 터 를 처리 할 수 있 습 니 다.
2.3 registerOnTouched
registerOnTouched(fn: any): void
폼 컨트롤 이 터치 되 었 을 때 registerOnTouched 방법 이 실 행 됩 니 다.구체 적 인 세부 사항 은 업데이트 되 어야 합 니 다.2018-1-31 11:18:332.4 setDisabledState
setDisabledState(isDisabled: boolean)?: void
업데이트 대기...2018-1-31 11:19:303 프로 그래 밍 절차
3.1 사용자 정의 폼 컨트롤 구성 요소 만 들 기
<div>
<h4> :{{countNumber}}</h4>
<br />
<div>
<button md-icon-button (click)="onIncrease()">
<span> </span>
<md-icon>add</md-icon>
</button>
<span style="margin-left: 30px;"></span>
<button md-icon-button (click)="onDecrease()">
<span> </span>
<md-icon>remove</md-icon>
</button>
</div>
</div>
HTML
import { Component, OnInit } from '@angular/core';
import { ControlValueAccessor } from '@angular/forms';
@Component({
selector: 'app-counter',
templateUrl: './counter.component.html',
styleUrls: ['./counter.component.scss']
})
export class CounterComponent implements OnInit {
countNumber: number = 0;
constructor() { }
ngOnInit() {
}
onIncrease() {
this.countNumber++;
}
onDecrease() {
this.countNumber--;
}
}
3.1.1 기능 설명증가 단 추 를 눌 렀 을 때 현재 계수 가 1 증가 하고 감소 단 추 를 눌 렀 을 때 현재 계수 가 1 증가 합 니 다.
3.1.2 다른 구성 요소 에서 직접 사용 할 때 오류 가 발생 합 니 다.
오류 보고 정 보 는 다음 과 같다.
오류 정 보 는 우리 가 사용 하 는 구성 요소
3.2
3.2.1 ControlValueAccessor 인터페이스 실현
export class CounterComponent implements OnInit, ControlValueAccessor {
countNumber: number = 0;
constructor() { }
ngOnInit() {
}
onIncrease() {
this.countNumber++;
}
onDecrease() {
this.countNumber--;
}
/** */
writeValue(obj: any): void {
}
/** */
registerOnChange(fn: any): void {
}
registerOnTouched(fn: any): void {
}
setDisabledState?(isDisabled: boolean): void {
}
}
3.2.2 의존 정보 제공 자 지정
import { Component, OnInit, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'app-counter',
templateUrl: './counter.component.html',
styleUrls: ['./counter.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CounterComponent),
multi: true
}
]
})
export class CounterComponent implements OnInit, ControlValueAccessor {
countNumber: number = 0;
constructor() { }
ngOnInit() {
}
onIncrease() {
this.countNumber++;
}
onDecrease() {
this.countNumber--;
}
/** */
writeValue(obj: any): void {
}
/** */
registerOnChange(fn: any): void {
}
registerOnTouched(fn: any): void {
}
setDisabledState?(isDisabled: boolean): void {
}
}
3.2.3 복구 대기 버그정상적으로 실행 할 수 있 지만 폼 컨트롤 의 요 소 는 폼 컨트롤 을 사용 하 는 구성 요소 에서 폼 모델 이 보 내 온 데 이 터 를 받 아들 일 수 없습니다.폼 컨트롤 이 변 한 데 이 터 는 폼 컨트롤 을 사용 하 는 구성 요소 의 폼 모델 로 전송 할 수 없습니다.한 마디 로 하면 모델 과 보기 사이 에 데이터 상호작용 을 할 수 없다 는 것 이다.
3.3 실습 모델 과 시도 한 데이터 의 상호작용
3.3.1 모델 보기
사용자 정의 폼 컨트롤 클래스 의 writeValue 방법 을 재 구성 합 니 다.
기교 01:writeValue 방법의 매개 변 수 는 사용자 정의 폼 컨트롤 을 사용 하 는 그 구성 요소 가 폼 의 데이터 바 인 딩 을 통 해 전 달 됩 니 다.
3.3.2 모델 로 보기
사용자 정의 폼 컨트롤 의 변화 데 이 터 를 처리 하 는 방법 을 사용자 정의 합 니 다.
propagateChange = (_: any) => {};
사용자 정의 폼 컨트롤 클래스 의 registerOnChange 방법 재 구성
/** */
registerOnChange(fn: any): void {
this.propagateChange = fn;
}
>데이터 가 변 하 는 곳 에서 사용자 정의 방법 을 호출 합 니 다.3.4 사용자 정의 폼 컨트롤 구성 요소 코드 집합
<div>
<h4> :{{countNumber}}</h4>
<br />
<div>
<button md-icon-button (click)="onIncrease()">
<span> </span>
<md-icon>add</md-icon>
</button>
<span style="margin-left: 30px;"></span>
<button md-icon-button (click)="onDecrease()">
<span> </span>
<md-icon>remove</md-icon>
</button>
</div>
</div>
HTML
import { Component, OnInit, forwardRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
@Component({
selector: 'app-counter',
templateUrl: './counter.component.html',
styleUrls: ['./counter.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CounterComponent),
multi: true
}
]
})
export class CounterComponent implements OnInit, ControlValueAccessor {
countNumber: number = 0;
propagateChange = (_: any) => {};
constructor() { }
ngOnInit() {
}
onIncrease() {
this.countNumber++;
this.propagateChange(this.countNumber);
}
onDecrease() {
this.countNumber--;
this.propagateChange(this.countNumber);
}
/** */
writeValue(obj: any): void {
this.countNumber = obj;
}
/** */
registerOnChange(fn: any): void {
/**fn , fn , */
this.propagateChange = fn; // fn this.propagateChange, this.propagateChange
}
registerOnTouched(fn: any): void {
}
setDisabledState?(isDisabled: boolean): void {
}
}
3.5 사용자 정의 폼 컨트롤 을 사용 하 는 그 구성 요소 의 코드 집합기술 01:사용자 정의 폼 컨트롤 과 사용자 정의 폼 컨트롤 을 사용 하 는 구성 요소 가 같은 모듈 에 없 을 때 사용자 정의 폼 컨트롤 에 대응 하 는 구성 요 소 를 내 보 내 고 가 져 와 야 합 니 다.
<div class="panel panel-primary">
<div class="panel-heading"> </div>
<div class="panel-body">
<h3> </h3>
</div>
<div class="panel-footer">2018-1-22 10:22:20</div>
</div>
<div class="panel-primary">
<div class="panel-heading"> </div>
<div class="panel-body">
<form #myForm=ngForm>
<app-counter name="counter" [(ngModel)]="countNumber">
</app-counter>
</form>
<h6> </h6>
<hr style="border: solid green 2px" />
<h6> </h6>
<h3> :{{myForm.value | json}}</h3>
</div>
<div class="panel-footer">2018-1-31 10:09:17</div>
</div>
<div class="panel-primary">
<div class="panel-heading"> </div>
<div class="panel-body">
<form #form="ngForm">
<p>outerCounterValue value: {{outerCounterValue}}</p>
<app-exe-counter name="counter" [(ngModel)]="outerCounterValue"></app-exe-counter>
<br />
<button md-raised-button type="submit">Submit</button>
<br />
<div>
{{form.value | json}}
</div>
</form>
</div>
<div class="panel-footer">2018-1-27 21:51:45</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">ngIf </div>
<div class="panel-body">
<button md-rasied-button (click)="onChangeNgifValue()"> ngif </button>
<br />
<div *ngIf="ngif; else ngifTrue" >
<h4 style="background-color: red; color: white" >ngif true</h4>
</div>
<ng-template #ngifTrue>
<h4 style="background-color: black; color: white">ngif false</h4>
</ng-template>
</div>
<div class="panel-footer">2018-1-27 16:58:17</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">RXJS </div>
<div class="panel-body">
<h4> </h4>
</div>
<div class="panel-footer">2018-1-23 21:14:49</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading"> </div>
<div class="panel-body">
<form (ngSubmit)="onTestLogin()" [formGroup]="loginForm">
<md-input-container>
<input mdInput placeholder=" " formControlName="username" />
</md-input-container>
<br />
<md-input-container>
<input mdInput placeholder=" " formControlName="userpwd" />
</md-input-container>
<br />
<button type="submit" md-raised-button> </button>
</form>
</div>
<div class="panel-footer">2018-1-23 11:06:01</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading"> </div>
<div class="panel-body">
<form [formGroup]="testForm">
<md-input-container>
<input mdInput type="text" placeholder=" " formControlName="email" />
<span mdSuffix>@163.com</span>
</md-input-container>
<br />
<md-input-container>
<input mdInput type="password" placeholder=" " formControlName="password" />
</md-input-container>
</form>
<hr />
<div>
<h2> :</h2>
<h4> :{{testForm.valid}}</h4>
<h4> :{{testForm.value | json}}</h4>
<h4> FormControl:{{testForm.controls['email'] }}</h4>
<hr />
<h2>email :</h2>
<h4> :{{testForm.get('email').valid}}</h4>
<h4>email :{{testForm.get('email').errors | json}}</h4>
<h4>required :{{testForm.hasError('required', 'email') | json}}</h4>
<h4>minLength :{{ testForm.hasError('minLength', 'email') | json }}</h4>
<h4>hello:{{ testForm.controls['email'].errors | json }}</h4>
<hr />
<h2>password :</h2>
<h4> :{{testForm.get('password').valid}}</h4>
<h4>password :{{testForm.get('password').errors | json }}</h4>
<h4>required :{{testForm.hasError('required', 'password') | json}}</h4>
</div>
<div>
<button nd-rasied-button (click)="onTestClick()"> </button>
<h4>data :{{data}}</h4>
</div>
</div>
<div class="panel-footer">2018-1-22 15:58:43</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading"> </div>
<div class="panel-body">
<md-input-container>
<input mdInput placeholder=" ( ):" [formControl]="name"/>
</md-input-container>
<div>
:{{name.value}}
</div>
</div>
<div class="panel-footer">2018-1-22 11:12:35</div>
</div> -->
<div class="panel panel-primary">
<div class="panel-heading"> </div>
<div class="panel-body">
<md-input-container>
<input mdInput placeholder=" " #a="ngModel" [(ngModel)]="desc" name="desc" />
<button type="button" md-icon-button mdSuffix (click)="onTestNgModelClick()">
<md-icon>done</md-icon>
</button>
</md-input-container>
<div>
<h3> desc :{{ a.value }}</h3>
</div>
</div>
<div class="panel-footer">2018-1-22 10:19:31</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">md-chekbox </div>
<div calss="panel-body">
<div>
<md-checkbox #testCheckbox color="primary" checked="true"> </md-checkbox>
</div>
<div *ngIf="testCheckbox.checked">
<h2> checkbox </h2>
</div>
</div>
<div class="panel-footer">2018-1-18 14:02:20</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">md-tooltip </div>
<div class="panel-body">
<span md-tooltip=" "> </span>
</div>
<div class="panel-footer">2018-1-18 14:26:58</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">md-select </div>
<div class="panel-body">
<md-select placeholder=" " class="fill-width" style="height: 40px;">
<md-option *ngFor="let taskList of taskLists" [value]="taskList.name">{{taskList.name}}</md-option>
</md-select>
</div>
<div class="panel-footer">2018-1-18 14:26:58</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">ngNonBindable </div>
<div class="panel-body">
<h3> </h3>
<p> ngNonBindable , </p>
<h3> </h3>
<p>
<span>{{taskLists | json }}</span>
<span ngNonBindable>← {{taskLists | json }} </span>
</p>
</div>
<div class="panel-footer">2018-1-19 09:34:26</div>
</div>
HTML
import { Component, OnInit, HostListener, Inject} from '@angular/core';
import { FormControl, FormGroup, FormBuilder, Validators } from '@angular/forms';
import { Http } from '@angular/http';
import { QuoteService } from '../../service/quote.service';
@Component({
selector: 'app-test01',
templateUrl: './test01.component.html',
styleUrls: ['./test01.component.scss']
})
export class Test01Component implements OnInit {
countNumber: number = 9;
outerCounterValue: number = 5;
ngif = true;
loginForm: FormGroup;
testForm: FormGroup;
data: any;
name: FormControl = new FormControl();
desc: string = 'hello boy';
taskLists = [
{label: 1, name: ' '},
{label: 2, name: ' '}
];
constructor(
private formBuilder: FormBuilder,
private http: Http,
@Inject('BASE_CONFIG') private baseConfig,
private quoteService: QuoteService
) {}
ngOnInit() {
this.testForm = new FormGroup({
email: new FormControl('', [Validators.required, Validators.minLength(4)], []),
password: new FormControl('', [Validators.required], [])
});
this.name.valueChanges
.debounceTime(500)
.subscribe(value => alert(value));
this.loginForm = this.formBuilder.group({
username: ['', [Validators.required, Validators.minLength(4), this.myValidator], []],
userpwd: ['', [Validators.required, Validators.minLength(6)], []]
});
this.quoteService.test()
.subscribe(resp => console.log(resp));
}
onChangeNgifValue() {
if (this.ngif == false) {
this.ngif = true;
} else {
this.ngif = false;
}
}
@HostListener('keyup.enter')
onTestNgModelClick() {
alert(' ');
}
onTestClick() {
// this.data = this.testForm.get('email').value;
// console.log(this.testForm.getError);
console.log(this.testForm.controls['email']);
}
onTestLogin() {
console.log(this.loginForm.value);
if (this.loginForm.valid) {
console.log(' ');
} else {
console.log(' ');
console.log(this.loginForm.controls['username'].errors);
console.log(this.loginForm.get('userpwd').errors);
}
}
myValidator(fc: FormControl): {[key: string]: any} {
const valid = fc.value === 'admin';
return valid ? null : {myValidator: {requiredUsername: 'admin', actualUsername: fc.value}};
}
}
3.6 초기 화 효과 전시이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Angular에서 타사 스크립트 및 CSS 작업Angular 방식으로 회로도가 있는 외부 라이브러리를 추가하거나 모듈을 가져옵니다. Angular.json은 Angular 프로젝트의 모든 설정 파일이며 표준 JavaScript 및 CSS 파일과 함께 타사 라이브...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.