国产99久久精品_欧美日本韩国一区二区_激情小说综合网_欧美一级二级视频_午夜av电影_日本久久精品视频

最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當前位置: 首頁 - 科技 - 知識百科 - 正文

淺析Angular19 自定義表單控件

來源:懂視網 責編:小采 時間:2020-11-27 22:20:22
文檔

淺析Angular19 自定義表單控件

淺析Angular19 自定義表單控件:1 需求 當開發者需要一個特定的表單控件時就需要自己開發一個和默認提供的表單控件用法相似的控件來作為表單控件;自定義的表單控件必須考慮模型和視圖之間的數據怎么進行交互 2 官方文檔 -> 點擊前往 Angular為開發者提供了ControlValueAcce
推薦度:
導讀淺析Angular19 自定義表單控件:1 需求 當開發者需要一個特定的表單控件時就需要自己開發一個和默認提供的表單控件用法相似的控件來作為表單控件;自定義的表單控件必須考慮模型和視圖之間的數據怎么進行交互 2 官方文檔 -> 點擊前往 Angular為開發者提供了ControlValueAcce

1 需求

當開發者需要一個特定的表單控件時就需要自己開發一個和默認提供的表單控件用法相似的控件來作為表單控件;自定義的表單控件必須考慮模型和視圖之間的數據怎么進行交互

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執行的方法,但是通常的做法是自定義一個方法 propagateChange 讓自定義的方法指向fn,這樣當數據變化時只需要調用 propagateChange 就可以對變化的數據進行處理

2.3 registerOnTouched

registerOnTouched(fn: any): void

表單控件被觸摸時會觸發registerOnTouched方法,具體細節待更新......2018-1-31 11:18:33

2.4 setDisabledState

setDisabledState(isDisabled: boolean)?: void

待更新......2018-1-31 11:19:30

3 編程步驟

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 直接在其他組件中使用時會報錯

 

報錯信息如下:

 

錯誤信息是說我們我們使用的組件<app-counter>還不是一個表單控件

3.2 如何讓<app-counter>組件變成一個表單控件組件

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 指定依賴信息providers

 

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 待修復bug

雖然可以正常運行,但是表單控件中的元素接受不到使用表單控件那個組件中表單模型傳過來的數據,表單控件變化的數據也無法回傳到使用表單控件那個組件中的表單模型中去;簡而言之,就是模型和視圖之間無法進行數據交互

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 初始化效果展示

 

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

淺析Angular19 自定義表單控件

淺析Angular19 自定義表單控件:1 需求 當開發者需要一個特定的表單控件時就需要自己開發一個和默認提供的表單控件用法相似的控件來作為表單控件;自定義的表單控件必須考慮模型和視圖之間的數據怎么進行交互 2 官方文檔 -> 點擊前往 Angular為開發者提供了ControlValueAcce
推薦度:
標簽: 自定義 19 表單
  • 熱門焦點

最新推薦

猜你喜歡

熱門推薦

專題
Top
主站蜘蛛池模板: 亚洲情a成黄在线观看动 | 日韩中文字幕第一页 | 国产精品一区二区午夜嘿嘿嘿小说 | 国产一区二区三区精品视频 | 91精品一区二区三区在线观看 | 一区二区三区免费 | 一级毛片免费毛片一级毛片免费 | 91久久精品国产91性色tv | 欧美日韩精品一区二区三区视频播放 | 99久久国产综合精品麻豆 | 一区二区视频在线观看 | 国产手机在线αⅴ片无码观看 | 日韩亚射 | 国产观看在线 | 国产资源视频在线观看 | 手机看片91精品一区 | 99精品视频在线观看免费 | 一级成人毛片免费观看 | 99久久免费国产精品特黄 | 亚洲欧美一区二区三区不卡 | a级网站| 91综合网 | 91大神在线观看精品一区 | 在线观看日韩视频 | 国产一区二区福利久久 | 亚洲五月婷婷 | 欧美亚洲一区二区三区在线 | 激情一区二区三区 | 欧美日韩亚洲一区二区三区在线观看 | 亚洲国产精品一区二区九九 | 亚洲精品99久久久久中文字幕 | 久久久xxx | 婷婷久草 | 毛片一级免费 | 亚洲国产精品成人综合久久久 | 水蜜桃网站 | 国产成人精品一区二区免费 | 亚洲午夜视频 | 欧美三页 | 国产精品久久毛片蜜月 | 国产中的精品一区的 |